这道题首先最重要的是要读懂题意,输出的是对应位置小球的重量,其实就是toposort后的顺序再用n+1减去就好,然后这道题还有两个重要的点:
1是要逆向构图,然后从序号大的到小的toposort就好,这样才能保证序列小的球质量尽量小;
2是要考虑重边的存在,不要重复的增加某一节点的入度值。
以下是代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int sum[205];
int map[205][205];
int judge[205];
int ans[205];
int n,m;
int main()
{
int t;
int x,y,yes;
cin>>t;
while(t--)
{
memset(sum,0,sizeof(sum));
memset(map,0,sizeof(map));
memset(judge,0,sizeof(judge));
memset(ans,0,sizeof(ans));
cin>>n>>m;
/* if(m==0)
{
for(int i=1;i<=n;i++)
{
if(i!=1) cout<<" ";
cout<<i;
}
cout<<endl;
continue;
}*/
//else
//{
yes=0;
for(int i=0;i<m;i++)
{
cin>>x>>y;
if(map[y][x]==0) sum[x]++;
map[y][x]=1;
//cout<<i<<" "<<y<<" "<<sum[y]<<endl;
if(map[x][y]==1) yes=1;
}
if(yes==1)
{
cout<<"-1"<<endl;
continue;
}
int cnt=0;
while(1)
{
int k=-1;
for(int i=n;i>=1;i--)
{
if(sum[i]==0&&judge[i]==0)
{
k=i;
judge[i]=1;
break;
}
}
//cout<<k<<endl;
if(k==-1) break;
judge[k]=1;
ans[k]=cnt;
cnt++;
for(int j=1;j<=n;j++)
{
if(map[k][j]==1) sum[j]--;
}
}
if(cnt!=n)
{
cout<<"-1"<<endl;
continue;
}
for(int i=1;i<=n;i++)
{
if(i!=1) cout<<" ";
cout<<n-ans[i];
}
cout<<endl;
//}
}
return 0;
}
再次感谢DISCUSS牛人提供的数据。。