题意:有n个人,每个人之间是单向喜欢的关系,问是否存在a喜欢b,b喜欢c,c喜欢a的三角恋关系。
条件:1 每个人之间都有一个单向的关系
2 三角恋就是成三元环
思路:因为每个人之间都有一个单向的关系,所以三角恋就是成环,成环一定会有三元环。采用拓扑排序来判断是否成环。
扩展:拓扑排序,就是有向图中每次把入度0的点放入队列中,然后该点指向的点入度减一,然后再找下一个入度为0的放入队列,然后出队列再重复。如果最后拓扑序列里面的总数小于n,就说明有环。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <list>
#include <set>
#include <queue>
#include <stack>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
char mp[2005][2005];//关系图
int num[2005];//入度记录
int topusort(int n)
{
queue<int>que;
for(int i=0;i<n;i++)
{
if(num[i]==0)
{
que.push(i);
}
}
int ans=0;
while(que.size())
{
int x=que.front();
que.pop();
ans++;
for(int i=0;mp[x][i]!='\0';i++)
{
if(mp[x][i]=='1')
{
num[i]--;
if(num[i]==0)
que.push(i);
}
}
}
if(n==ans)return 0;
else return 1;
}
int main()
{
int t,t1=0;
scanf("%d",&t);
while(t--)
{
memset(num,0,sizeof(num));
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",mp[i]);
for(int j=0;mp[i][j]!='\0';j++)
{
if(mp[i][j]=='1')
num[j]++;
}
}
int flag;
flag=topusort(n);
printf("Case #%d: ",++t1);
if(flag==1)
printf("Yes\n");
else
printf("No\n");
}
}
总结:1 当时想到拓扑序列,可是不够熟练,然后没有读出题目中每个人之间都有一个单向的关系的条件,所以一直卡在怎么找三元环的中。