拓扑(1)

Triangle LOVE

Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format: %I64d      Java class name: Main
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). Ai,j = 1 means i-th people loves j-th people, otherwise Ai,j = 0.
It is guaranteed that the given relationship is a tournament, that is, Ai,i= 0, Ai,j ≠ Aj,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

Sample Output

Case #1: Yes
Case #2: No

假设一个四元环:A -> B -> C -> D -> A ,无论 A -> C or C -> A 都会出现三元环,所有直接判断是否存在环即可。
#include<cstdio>
using namespace std;
const int maxn = 2e3+5;
char ch[maxn][maxn];
int num[maxn][maxn];
int in_degree[maxn];
int main(){
    int T,cas = 0;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i = 0; i < n; i++)
            in_degree[i] = 0;
        for(int i = 0; i < n; i++){
            scanf("%s",ch[i]);
            for(int j = 0; j < n; j++)
                if(ch[i][j]=='0')
                num[i][j] = 0;
                else {
                    num[i][j] = 1;
                    in_degree[j]++;//入度[j]++;统计有多少条边指向j节点。
                }
        }
        bool flag = 0;
        int j;
        for(int i = 0; i < n-2; i++){//删除n-2条边即可。
            for(j = 0; j < n; j++)
            if(in_degree[j]==0)//查找入度为零的节点
                break;
            if(j==n){//没有入度为零的节点必然存在环(所有节点入度不为零,所有节点必然有进有出,必然构成环)
                flag = 1;break;
            }
            else {
                in_degree[j] = -1;//删除入度为零的节点
                for(int k = 0; k < n; k++)
                    if(num[j][k] == 1)
                    in_degree[k] --;//同时删除入度为零的节点的边
            }
        }
        printf("Case #%d: ",++cas);
        if(flag)printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

 

posted @ 2015-08-26 14:59  Tobu  阅读(120)  评论(0)    收藏  举报