HDU
来源:互联网 发布:怎样推广淘宝网店 编辑:程序博客网 时间:2024/06/01 09:06
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857
题目大意:在满足先后顺序的前提下,让号码小的尽量在前
解题思路:一开始想到了一定是取出最小的然后依次拓扑下去,后来找了个反例5->1,3->2,正确顺序应该是5,1,3,2。那么如何解决这个问题呢,我们发现,首先要找出最小的数字所在的位置,把他们放到最前面,之后找次小的放在次前面,那么反过来就是最大的放到最后面,通过反向的拓扑排序,把最大的先取出来即可。
参考博客:http://blog.csdn.net/u012861385/article/details/38059515
AC代码:
#include<cstdio>#include<cstring>#include<queue>using namespace std;const int MAXN = 30000 + 5;const int MAXM = 100000 + 5;struct Edge{ int v, next; Edge(int v=0,int next=0):v(v),next(next){}}edge[MAXM];int head[MAXN],edgnum;int indegr[MAXN];int ans[MAXN], tot;void toInit(){ memset(head, -1, sizeof(head)); memset(indegr, 0, sizeof(indegr)); edgnum = 0; tot = 0;}void toAdd(int u,int v){ edge[edgnum] = Edge(v, head[u]); head[u] = edgnum++;}void toBfs(int n){ priority_queue<int> qi; for (int i = 1;i <= n;++i) if (!indegr[i]) qi.push(i); while (!qi.empty()) { int u = qi.top();qi.pop(); ans[tot++] = u; for (int i = head[u];i != -1;i = edge[i].next) { int v = edge[i].v; indegr[v]--; if (!indegr[v]) qi.push(v); } }}int main(){ int t;scanf("%d", &t); while (t--) { int n, m; scanf("%d%d", &n, &m); toInit(); for (int i = 1;i <= m;++i) { int u, v; scanf("%d%d", &v, &u); toAdd(u, v); indegr[v]++; } toBfs(n); for (int i = tot - 1;i > 0;--i) printf("%d ", ans[i]); printf("%d\n", ans[0]); } return 0;}