题目地址: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;
}