Time Limit: 1500 MS
Memory Limit: 256 MB
给定一个简单无向图, 请你判断这个图是否海星, 一个图海星当且仅当它内部存在五个互不相同的点 A , B , C , D , E A,B,C,D,E A,B,C,D,E, 满足点对 < A , C > , < A , D > , < B , D > , < B , E > , < C , E > <A,C>,<A,D>,<B,D>,<B,E>,<C,E> <A,C>,<A,D>,<B,D>,<B,E>,<C,E>之间都存在一条边。
#####Input
第一行包含一个正整数 T,表示有 T组测试数据。
接下来依次描述每组测试数据。对于每组测试数据:
第一行包含一个正整数 n,表示给定图的点数。接下来有 n 行,每行有一个长度为 n 的 01 字符串,表示给定图的邻接矩阵
G
G
G,
x
x
x 和
y
y
y 之间有边相连当且仅当
G
x
y
=
1
Gxy=1
Gxy=1。
数据保证 1 ≤ T ≤ 100 1≤T≤100 1≤T≤100 , 1 ≤ n ≤ 200 1≤n≤200 1≤n≤200 , G x x = 0 Gxx=0 Gxx=0 以及 G x y = G y x Gxy=Gyx Gxy=Gyx ,对于 70% 的数据额外满足 1 ≤ n ≤ 50 1≤n≤50 1≤n≤50
#####Output
对于每组测试数据输出一行, 先输出信息"Case #x: “,其中x表示这是第 x x x组测试数据, 随后如果该组给出的图海星,输出"Starfish!”,否则输出"Walk Walk"。所有输出不含引号。
Sample Input
3
3
011
101
110
5
01111
10111
11011
11101
11110
2
00
00
Sample Output
Case #1: Walk Walk
Case #2: Starfish!
Case #3: Walk Walk
题解:
bitset应用。对每个点存储一个与他之间有一条边的点的集合。然后枚举点A,B,C,求AB集合交集tempAB和BC集合交集tempBC,从tempAB中去掉点C,tempBC中去掉点A后取他们俩的并集。并集大小大于等于2则存在海星。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define INF 1999122700LL
using namespace std;
int n;
char mp[204][204];
bitset<204>a[204];
int w33ha(int CASE){
scanf("%d",&n);
for(int i=1;i<=n;i++)a[i].reset();
for(int i=1;i<=n;i++)scanf("%s",mp[i]+1);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(mp[i][j]=='1')a[i].set(j);
}
}
printf("Case #%d:",CASE);
for(int A=1;A<=n;A++){
for(int B=1;B<=n;B++){
for(int C=1;C<=n;C++){
if(A==B||B==C||A==C)continue;
if(mp[A][C]=='0')continue;
bitset<204>ta=a[A],tb=a[B],tc=a[C],tempAB,tempBC,temp;
tempAB=ta&tb;tempAB.reset(C);
tempBC=tc&tb;tempBC.reset(A);
if(tempAB.count()==0||tempBC.count()==0)continue;
temp=tempAB|tempBC;
if(temp.count()<2)continue;
else return puts(" Starfish!"),0;
}
}
}
puts(" Walk Walk");
return 0;
}
int LiangJiaJun(){
int T;scanf("%d",&T);
for(int i=1;i<=T;i++)w33ha(i);
return 0;
}