DAG即Directed Acyclic Graph,有向无环图.用DAG可以描述一些有依赖关系的任务组,而这些任务还有另外一个属性,即都有一个权重,标示这个任务的重要性.
我们需要你来实现一个算法,对DAG里面的节点进行排序,保证排序不违背DAG的依赖关系,即一个任务A如果排在任务B前面,那么在DAG中不能存在由B到A的路径.另外一个要求就是,让权重大的任务尽量优先执行.
DAG即Directed Acyclic Graph,有向无环图.用DAG可以描述一些有依赖关系的任务组,而这些任务还有另外一个属性,即都有一个权重,标示这个任务的重要性.
我们需要你来实现一个算法,对DAG里面的节点进行排序,保证排序不违背DAG的依赖关系,即一个任务A如果排在任务B前面,那么在DAG中不能存在由B到A的路径.另外一个要求就是,让权重大的任务尽量优先执行.
在第一行给定DAG的节点数n和边数e.
后面n行,每一行是 节点的 标号和权重, seq weight.
最后e行,每一行是对于边的描述, s t.
排序好的节点标号,在一行内输出,空格隔开.
4 4 1 2 2 3 3 5 4 4 1 2 1 3 2 4 3 4
1 3 2 4
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.PriorityQueue; class Vertex { int lable; //标号 int weight; //权值 int in; //入度 ArrayList<Vertex> connectList; //该顶点所指向的点 Vertex(int lable, int weight) { this.lable = lable; this.weight = weight; this.connectList = new ArrayList<Vertex>(); } } /** * 拓扑排序 * * @author wylu */ public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] strs = br.readLine().split(" "); int n = Integer.parseInt(strs[0]), e = Integer.parseInt(strs[1]); //建图 HashMap<Integer, Vertex> dag = new HashMap<Integer, Vertex>(); for (int i = 0; i < n; i++) { strs = br.readLine().split(" "); int lable = Integer.parseInt(strs[0]), weight = Integer.parseInt(strs[1]); dag.put(lable, new Vertex(lable, weight)); } for (int i = 0; i < e; i++) { strs = br.readLine().split(" "); int from = Integer.parseInt(strs[0]), to = Integer.parseInt(strs[1]); dag.get(from).connectList.add(dag.get(to)); dag.get(to).in++; } ArrayList<Integer> res = topologicalSort(dag); for (int i = 0; i < res.size() - 1; i++) { System.out.print(res.get(i) + " "); } System.out.println(res.get(res.size() - 1)); } private static ArrayList<Integer> topologicalSort(HashMap<Integer, Vertex> dag) { ArrayList<Integer> res = new ArrayList<>(); //大顶堆 PriorityQueue<Vertex> queue = new PriorityQueue<>(new Comparator<Vertex>() { @Override public int compare(Vertex o1, Vertex o2) { return -Integer.compare(o1.weight, o2.weight); } }); //入度为0的点入队 for (Integer lable : dag.keySet()) { if (dag.get(lable).in == 0) queue.offer(dag.get(lable)); } while (!queue.isEmpty()) { Vertex fromV = queue.poll(); res.add(fromV.lable); for (Vertex toV : dag.get(fromV.lable).connectList) { toV.in--; //邻接点入度减1 if (toV.in == 0) queue.offer(toV); } } return res; } }
n, e = map(int, input().split()) vertex = dict() for _ in range(n): v, w = map(int, input().strip().split()) vertex[v] = w for _ in range(e): start, end = map(int, input().strip().split()) vertex[start] += vertex[end] for node, _ in sorted(vertex.items(), key=lambda x: -x[1]): print(node, end=' ')
#include <bits/stdc++.h> using namespace std; struct P{ int u, w; friend bool operator > (P p1, P p2){ return p1.w < p2.w; } }; int main(){ int n, m, u, v, w; scanf("%d%d", &n, &m); vector<P> node(n+1); vector<int> d(n+1, 0); vector<bool> vis(n+1, false); vector<int> edge[n+1]; vector<int> r; for(int i=0;i<n;i++){ scanf("%d%d", &u, &w); node[i+1] = {u, w}; } for(int i=0;i<m;i++){ scanf("%d%d", &u, &v); edge[u].push_back(v); d[v]++; } priority_queue<P, vector<P>, greater<P> > q; for(int i=1;i<=n;i++) if(d[i] == 0){ q.push(node[i]); vis[i] = true; } while(!q.empty()){ int t = q.size(); while(t--){ P p = q.top(); q.pop(); u = p.u; w = p.w; for(auto &v: edge[u]) d[v]--; r.push_back(u); } for(int i=1;i<=n;i++) if(d[i]==0 && !vis[i]){ q.push(node[i]); vis[i] = true; } } for(int i=0;i<n;i++) printf("%d ", r[i]); return 0; }
#include <iostream> #include <vector> #include <queue> #include <algorithm> using namespace std; int main(void) { int n, e; cin >> n >> e; vector<int> weights(n + 1); int seq, w; for (int i = 0; i < n; ++i) { cin >> seq >> w; weights[seq] = w; } int u, v; vector<vector<int>> g(n + 1); vector<int> indegrees(n + 1, 0); for (int i = 0; i < e; ++i) { cin >> u >> v; g[u].emplace_back(v); ++indegrees[v]; } priority_queue<pair<int, int>> q; // maximum heap for (int u = 1; u <= n; ++u) if (!indegrees[u]) q.emplace(weights[u], u); while (not q.empty()) { const auto [weight, curr] = q.top(); q.pop(); cout << curr << ' '; for (const int nxt : g[curr]) if (!--indegrees[nxt]) q.emplace(weights[nxt], nxt); } return 0; }
//图的拓扑排序,权值大的优先 //首先输出入度为0的,入度为0的有多个比较权值 //数组记录每个点的权值 //map记录点的拓扑关系 import java.util.Scanner; import java.util.Map; import java.util.HashMap; import java.util.ArrayList; public class Main{ public static void main(String[] args){ Scanner in = new Scanner(System.in); int n = in.nextInt(); int e = in.nextInt(); int []weight = new int[n+1]; int []inDegree = new int[n+1]; Map<Integer,ArrayList<Integer>> map = new HashMap<>(); for(int i=1;i<=n;i++){ int t = in.nextInt(); weight[t] = in.nextInt(); } for(int i=0;i<e;i++){ int tmp1 = in.nextInt(); int tmp2 = in.nextInt(); inDegree[tmp2]++; if(map.containsKey(tmp1)) map.get(tmp1).add(tmp2); else { map.put(tmp1,new ArrayList<Integer>()); map.get(tmp1).add(tmp2); } } //首先遍历树的入度,将入度为0的点,加入输出队列 Map<Integer,Integer> print = new HashMap<>(); for(int i=1;i<=n;i++){ if(inDegree[i]==0){ print.put(i,weight[i]); } } //输出print中权值最大的节点 StringBuilder builder = new StringBuilder(); while(!print.isEmpty()){ int pos = getPos(print); builder.append(pos); builder.append(" "); print.remove(pos); //对pos的下一跳处理 ArrayList<Integer> list = map.get(pos); if(list!=null){ for(int i:list){ inDegree[i]-=1; if(inDegree[i]==0){ print.put(i,weight[i]); } } } } builder.deleteCharAt(builder.length()-1); System.out.println(builder.toString()); } public static int getPos(Map<Integer,Integer> print){ int pos = 0,max = 0; for(int key:print.keySet()){ if(print.get(key)>max){ max = print.get(key); pos = key; } } return pos; } }
#include <iostream> #include <vector> #include <algorithm> #include <queue> using namespace std; struct cmp { bool operator()(pair<int,int>& a, pair<int,int>& b) { return a.second < b.second; } }; int main() { int n,a,b,e; cin >> n >> e; vector<pair<int,int>> node(n + 1); vector<int> degree(n + 1,0); vector<bool> vis(n + 1,false); vector<vector<int>>edge(n + 1); for(int i = 0; i < n; i++) { cin >> a >> b; node[i + 1] = {a,b}; } vector<int> res; for(int i = 0; i < n; i++) { cin >> a >> b; edge[a].push_back(b); degree[b]++; } priority_queue<pair<int,int>,vector<pair<int,int>>, cmp> pq; for(int i = 1; i <= n; i++) { if(degree[i] == 0) pq.push(node[i]),vis[i] = true; } while(pq.size()) { int x = pq.size(); while(x--) { auto tmp = pq.top(); pq.pop(); int first = tmp.first; int second = tmp.second; for(int i = 0; i < edge[first].size(); i++) { degree[edge[first][i]]--; } res.push_back(tmp.first); } for(int i = 1; i <= n; i++) { if(degree[i] == 0 && !vis[i]) pq.push(node[i]),vis[i] =true; } } for(int i = 0 ; i < n; i++) { cout << res[i] << " "; } cout << endl; }