题目链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4124
传递闭包
没想到Floyd 还有这种骚操作
学到了 我的博客
https://blog.csdn.net/flymoyu/article/details/90298395
看完上面的讲解 我想你应该已经会了 如果不会 直接看代码 相信你可以的 ,,,,
若是代码看不懂 那么请了解一下 Floyd最短路算法 加油
这道题的关键点
- 如果 u==v 那么全部输出零
- 如果mp[i][j]==1&&mp[j][i]==1 全部输出零
- 出度等于入度 且小于 n/2 输出一
代码奉上
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int mp[200][200];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
mp[i][j]=0;
}
}
int u,v;
int flag=0;
while(m--)
{
scanf("%d%d",&u,&v);
if(u==v)
flag=1;
mp[u][v]=1;
}
//cout<<flag<<endl;
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
mp[i][j]|=mp[i][k]&mp[k][j];
}
}
}
/* for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<mp[i][j]<<" ";
cout<<endl;
}*/
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(mp[i][j]==1&&mp[j][i]==1)
flag=1;
}
}
if(flag)
{
for(int i=1;i<=n;i++)
{
printf("0");
}
printf("\n");
continue;
}
int in[200],out[200];
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i!=j&&mp[i][j])
{
out[i]++;
in[j]++;
}
}
}
/*for(int i=1;i<=n;i++)
{
cout<<in[i]<<" "<<out[i]<<endl;
}*/
for(int i=1;i<=n;i++)
{
if(out[i]>n/2||in[i]>n/2)
{
printf("0");
}
else
{
printf("1");
}
}
printf("\n");
}
return 0;
}