2 5 00100 10000 01001 11101 11000 5 01111 00000 01000 01100 01110
Case #1: Yes Case #2: No
题意:给出你所有人的关系,然后让你判断一下是否存在三角恋或多角恋。
分析:我们可以根据关系建一个有向图,假如A喜欢B那么就让A指向B,假如存在三角恋或多角恋那么肯定会形成一个环,我选择用拓扑排序,如果形成环的话肯定不会把所有的数都排序。
注意:用链式前向星的话,边的数组要开到2000*1999之上,,RE了好几次。
心得: 比赛的时候没有想到拓扑,只是想到了并查集,左后还是没有做出来。
并查集可以判断一棵树是不是成环,拓扑才可以判断一个图是不是成环。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 2005
struct node{
int to, next;
}s[20000005];
int in[M], head[M], n, tot, queue[M];
char map[M][M];
void getmap(int a, int b){
s[tot].to = b;
in[b]++;
s[tot].next = head[a];
head[a] = tot++;
}
int toposort(){
bool vis[M];
memset(vis, false, sizeof(vis));
int i, j, iq = 0;
for(i = 0; i < n; i ++){
if(!in[i]){
queue[iq++] = i;
vis[i] = 1;
}
}
for(i = 0; i < iq; i++){
int temp = head[queue[i]];
for(j = temp; j != -1; j = s[j].next){
if(!(--in[s[j].to])){
queue[iq++] = s[j].to;
}
}
}
if(iq < n) return 1;
else return 0;
}
int main(){
int t, v = 1;
scanf("%d", &t);
while(t --){
memset(in, 0, sizeof(in));
memset(head, -1, sizeof(head));
tot = 0;
scanf("%d", &n);
int i, j, flag;
for(i = 0; i < n; i ++){
scanf("%s", map[i]);
for(j = 0; j < n; j ++){
if(map[i][j] == '1'){
getmap(i, j);
}
}
}
printf("Case #%d: ", v++);
flag = toposort();
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}原文:http://blog.csdn.net/shengweisong/article/details/40039621