标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857
逆序建图,编号大的往前排,倒序输出。
为什么要这么做呢?
首先这是要求编号小的尽量排在前面,而不是字典序最小。例如:
1
3 1
3 1
那么字典序最小的话就是 2 3 1,而 1 却应该在 2 的前面,这样正确答案就应该是3 1 2。
怎么办呢?首先把图的有向边全部逆过来然后倒序输出拓扑排序,也是正向拓扑排序的一种方案,那么对于每一次删边之后得到的所有入度为 0 的点,把其添加到优先队列中,编号大的排在前面,倒序输出后就是编号大的排在后面,这样就解决了。
提交的时候有超时问题,原因是过多使用了memset 函数……
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> #define maxn 30010 using namespace std; struct Edge { int u, v; Edge(int x, int y):u(x), v(y) {} }; vector<Edge> edges; vector<int> G[maxn]; priority_queue<int> Q; bool operator == (const Edge a, const Edge b) { return a.u == b.u && a.v == b.v; } int main() { int t; scanf("%d",&t); while (t > 0) { t--; int into[maxn] = {0}; int List[maxn] = {0}; bool f[maxn] = {0}; int n, m; scanf("%d%d",&n,&m); for (int i=0; i<m; i++) { int x, y; scanf("%d%d",&x,&y); Edge e(y,x); edges.push_back(e); G[y].push_back(edges.size()-1); into[x]++; } for (int i=1; i<=n; i++) if (into[i] == 0) Q.push(i); for (int i=0; i<n; i++) { int j = Q.top(); Q.pop(); List[i] = j; f[j] = true; for (int k=0; k<G[j].size(); k++) { into[edges[G[j][k]].v]--; if (into[edges[G[j][k]].v] == 0 && !f[edges[G[j][k]].v]) Q.push(edges[G[j][k]].v); } } for (int i=n-1; i>0; i--) printf("%d ",List[i]); printf("%d\n",List[0]); for (int i=0; i<=n; i++) G[i].clear(); edges.clear(); while (!Q.empty()) Q.pop(); } return 0; }
标签:
原文地址:http://blog.csdn.net/qust1508060414/article/details/51344158