HDOJ4324 Triangle LOVE --- 拓扑排序

题目链接 http://acm.hdu.edu.cn/viewerror.php?rid=27085135

Problem Description

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,要么a爱b,要么b爱a,不存在两个人相爱或者都不爱对方。给定t组测试样例,每组给个n维方阵,方阵中, 方阵中i行j列(1开始算)为1表示i爱j。 判定是否存在三角恋,即a爱b,b爱c,c爱a。

 题解:

这道题其实就是一个裸的拓扑排序,只是我太笨,在想环的时候忽略了任意两点间必有连接的条件,然后就没想到怎么做,看了别人的题解才恍然大悟。。。

这题就直接走一遍拓扑排序,用邻接表的形式建图,建图时记录每个点的入度。

建图完后,一个for循环遍历将所有入度为0的点入队列,然后while循环取队首元素,将于队首元素邻接的点入度都减1,同时判断减1后入度是否为0,若是则入队。 每次取队首时,用一个计数器+1记录节点个数,最后判断计数器是否等于n,不等于的话则存在环,否则无环。

这道题就是先拓扑判断是否存在n元环,n元环必定存在a->b->c-这样的连接情况,如果c->a,那么直接就形成三元环满足题意了,如果a->c,那就排除掉b点剩下一个n-1元环,这样一直迭代下去一定会形成三元环a->b->c->a。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#define MAXN 2010
using namespace std;
int n;
vector<int> vec[MAXN];
queue<int> q;
char ch[MAXN];
int degree[MAXN]; // 存度数
// 初始化
void Init() {
    memset(degree,0,sizeof(degree));
    while(!q.empty()) q.pop();
    for(int i = 1;i <= n;i++) vec[i].clear();
}

// 拓扑排序判环
bool TopoLogical() {
    for(int i = 1;i <= n;i++) {
        if(degree[i] == 0) {
            q.push(i);
        }
    }
    int cnt = 0;// 拓扑排序的节点数
    int top;
    int size;
    while(!q.empty()) {
        top = q.front();
        q.pop();
        cnt++;
        size = vec[top].size();
        for(int i = 0;i < size;i++) {
            degree[vec[top][i]]--;
            if(degree[vec[top][i]] == 0) {
                q.push(vec[top][i]);
            }
        }
    }
    if(cnt != n) {
        // 有环
        return true;
    }
    return false;
}

int main()
{
    int t;
    int Case = 1;
    scanf("%d",&t);
    while(t--) {
       scanf("%d",&n);
       Init();
       int len;
       for(int i = 1;i <= n;i++) {
           scanf("%s",ch+1);
           len = strlen(ch+1);
           for(int j = 1;j <= len;j++) {
               if(ch[j] == '1') {
                   vec[i].push_back(j);
                   degree[j]++;
               }
           }
       }
       bool flag = TopoLogical();// 有环标记
       printf("Case #%d: ",Case++);
       if(flag == true) {
           printf("Yes\n");
       } else {
           printf("No\n");
       }
       
    }
    
    return 0;
} 

 

阅读更多
换一批

没有更多推荐了,返回首页