HDU 4324 Triangle LOVE 【判环+拓扑】

版权声明:转载的时候记着点个赞再评论一下! https://blog.csdn.net/LOOKQAQ/article/details/82048090

Time limit

1000 ms

Memory limit

65536 kB

Recently, scientists find that there is love between any of two people. For example, between A and B, if A don’t love B, then B must love A, vice versa. And there is no possibility that two people love each other, what a crazy world! 
Now, scientists want to know whether or not there is a “Triangle Love” among N people. “Triangle Love” means that among any three people (A,B and C) , A loves B, B loves C and C loves A. 
  Your problem is writing a program to read the relationship among N people firstly, and return whether or not there is a “Triangle Love”. 

Input

The first line contains a single integer t (1 <= t <= 15), the number of test cases.
For each case, the first line contains one integer N (0 < N <= 2000). 
In the next N lines contain the adjacency matrix A of the relationship (without spaces). A i,j = 1 means i-th people loves j-th people, otherwise A i,j = 0. 
It is guaranteed that the given relationship is a tournament, that is, A i,i= 0, Ai,j ≠ A j,i(1<=i, j<=n,i≠j).

Output

For each case, output the case number as shown and then print “Yes”, if there is a “Triangle Love” among these N people, otherwise print “No”. 
Take the sample output for more details. 

Sample Input

2
5
00100
10000
01001
11101
11000
5
01111
00000
01000
01100
01110
  • 思路:由题意可以知道,对于任意给定的一个有环图,一定存在着三元环(想想这是为啥?)
  •     假设有环上三个相邻的点a-> b-> c
  • 如果c->a有边 就已经形成了一个三元环
  • 如果c->a没边 那么a->c肯定有边 这样就形成了一个n-1元环 递归即可
  • 拓扑解决
  • #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    const int maxn =2e3+10;
    char map[maxn][maxn];
    int indeg[maxn],n;
    vector<int>G[maxn]; //邻接表存图
    queue<int>q;
    void topsort()
    {
        int num=0;
        while(!q.empty())
            q.pop();
        for(int i=0;i<n;i++)  //将入度为0的点加入队列
        {
            if(!indeg[i])
                q.push(i);
        }
        while(!q.empty())
        {
            int now = q.front();
            q.pop();
            num++;
            //这一步是判断与now相连的边在入度-1的情况下是否为0
            for(int i=0;i<G[now].size();i++) 
            {
                if(--indeg[G[now][i]]==0)
                    q.push(G[now][i]);  //入度为0的话进入队列
            }
        }
        if(num!=n)
            printf("Yes\n");
        else
            printf("No\n");
    }
    int main()
    {
        int t,cas=1;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            memset(indeg,0,sizeof(indeg)); //入度初始化为0
            for(int i=0;i<n;i++)  //清空
                G[i].clear();
            for(int i=0;i<n;i++)
            {
                getchar();
                scanf("%s",map[i]);
                for(int j=0;j<n;j++)
                {
                    if(map[i][j]=='1')
                    {
                        G[i].push_back(j);  
                        indeg[j]++;    //i-->j有一条边,j的入度加一
                    }
                }
            }
            printf("Case #%d: ",cas++);
            topsort();
        }
        return 0;
    }
  •  

猜你喜欢

转载自blog.csdn.net/LOOKQAQ/article/details/82048090
今日推荐