题目地址:http://poj.org/problem?id=3687
好坑的一道题!!!我来说说需要注意的地方。。
1:输入是a比b重,也就是说需要逆向建图。
2:找的时候需要从后往前找(不明白?看下一条)。
3:最终的输出是输出的哪个球是第几轻的!!比如,根据前两条得到的拓扑序列为3,2, 4, 1, 5。那么应该输出4,2,1,3,5.因为第1个球是第4轻的,第2个球是第2轻的。。。以此类推。。现在应该明白上述两条的原因了吧。。
代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <algorithm> using namespace std; int d[300], head[300], n, cnt, a[300], b[300]; struct node { int u, v, w; int next; } edge[50000]; void add(int u, int v, int w) { edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } void tops() { int i, j, s=0, flag=0, x, u; while(1) { x=0; for(j=n; j>=1; j--) { if(d[j]==0) { u=j; b[s++]=j; d[j]--; x=1; break; } } if(x==0&&s<n) { flag=1; break; } if(s==n) break; for(j=head[u]; j!=-1; j=edge[j].next) { if(edge[j].w==1) { edge[j].w--; d[edge[j].v]--; } } } if(flag) printf("-1\n"); else { for(i=1; i<=s; i++) { for(j=0;j<n;j++) { if(i==b[j]) { if(i==s) printf("%d\n",n-j); else printf("%d ",n-j); } } } } } int main() { int t, a, b, m, flag; scanf("%d",&t); while(t--) { memset(d,0,sizeof(d)); memset(head,-1,sizeof(head)); cnt=0; flag=0; scanf("%d%d",&n,&m); while(m--) { scanf("%d%d",&a,&b); d[a]++; if(a==b) flag=1; add(b,a,1); } if(flag) printf("-1\n"); else tops(); } return 0; }