题意:
有N个质量分别为1~N的球,对他们进行编号,编号为1~N,且必须满足以下要求:
任意两个球的编号都不相同。
然后还会给出一些约束条件(a,b),表示编号为a的球比编号为b的球要轻。
如果能满足所有的约束条件,则依次输出编号1~N的球的质量,同时要使编号为1的球的质量尽可能小,在满足前面条件的情况下编号为2的球的质量尽可能小。。。
如果 不能满足则输出-1.
做法:
逆向拓扑排序
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N=205,MAX=205;
int mat[N][N];
int in[N],out[N],rec[N],rec1[N],vis[N];
int n,m,t;
int toposort(int n,int mat[][MAX],int* ret)
{
int d[MAX],i,j,k;
for (i=1;i<=n;i++)
for (d[i]=0,j=1;j<=n;d[i]+=mat[i][j++]); //这次数组d保存的是出度
for (k=n;k>0;ret[i]=k--) //编号为i的球的质量为k
{
for (i=n;d[i]&&i>0;i--);
if (i==0)
return 0;
for (d[i]=-1,j=1;j<=n;j++)
d[j]-=mat[j][i];
}
return 1;
}
int main()
{
int t,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(mat,0,sizeof(mat));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
if(!mat[a][b])
{
mat[a][b]=1;
in[b]++;
out[a]++;
}
}
if(toposort(n,mat,rec1))
{
for(int i=1;i<n;i++)
printf("%d ",rec1[i]);
printf("%d\n",rec1[n]);
}
else
printf("-1\n");
}
}
================
以前写的