POJ3687-反向拓扑排序
来源:互联网 发布:微信群加人软件免费版 编辑:程序博客网 时间:2024/05/21 11:16
/*题意为拓扑排序,使得小的结点尽可能的排在前面:如:5->6->1; 4->3->2 应让结点1尽量排在前面,再使2尽量排在前面... ...:5 6 1 4 3 2若直接按结点从小到大拓扑排序,无法得到正解:4 3 2 5 6 1反向拓扑排序,按结点从大到小的顺序这样能使结点小的尽可能的排在后面:2 3 4 1 6 5,那么反过来的5 6 1 4 3 2就是所求的拓扑序列,再编上号:5(1),6(2),1(3),4(4),3(5),2(6)即可。*/#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>using namespace std;int n,m,chu[250];vector<int> adj[250];struct node{ int v; node(){} node(int vv):v(vv){} bool operator<(const node a)const{ return a.v>v; }};int s[250],lab[250],cnt;bool solve(void){ priority_queue<node> q; for (int i=1; i<=n; i++) if (!chu[i]) q.push(node(i)); if (q.empty()) return false; cnt=0; while (!q.empty()) { int u=q.top().v; q.pop(); s[cnt++]=u; for (int i=0; i<adj[u].size(); i++) { int v=adj[u][i]; if (--chu[v]==0) q.push(node(v)); } } if (cnt<n) return false; for (int i=0; i<cnt; i++) lab[s[i]]=n-i; printf("%d",lab[1]); for (int i=2; i<=n; i++) printf(" %d",lab[i]); printf("\n"); return true;}int main(){ int cas; scanf("%d",&cas); while (cas--) { scanf("%d%d",&n,&m); for (int i=1; i<=n; i++) { chu[i]=0; adj[i].clear(); } int x,y; for (int i=1; i<=m; i++) { scanf("%d%d",&x,&y); adj[y].push_back(x); chu[x]++; } if (!solve()) printf("-1\n"); } return 0;}