Catch
Time Limit: 2000/1000 MS
(Java/Others) Memory
Limit: 32768/32768 K (Java/Others)Total Submission(s):
782 Accepted
Submission(s): 389
Problem Description
A thief is running away!
We can consider the city where he locates as an undirected graph in
which nodes stand for crosses and edges stand for streets. The
crosses are labeled from 0 to N–1.The tricky thief starts his escaping from cross S. Each moment he
moves to an adjacent cross. More exactly, assume he is at cross u
at the moment t. He may appear at cross v at moment t + 1 if and
only if there is a street between cross u and cross v. Notice that
he may not stay at the same cross in two consecutive moment.
The cops want to know if there’s some moment at which it’s possible
for the thief to appear at any cross in the city.
Input
The input contains multiple test cases:
In the first line of the input there’s an integer T which is the
number of test cases. Then the description of T test cases will be
given.For any test case, the first line contains three integers N (≤ 100
000), M (≤ 500 000), and S. N is the number of crosses. M is the
number of streets and S is the index of the cross where the thief
starts his escaping.
For the next M lines, there will be 2 integers u and v in each line
(0 ≤ u, v < N). It means there’s an undirected
street between cross u and cross v.
Output
For each test case, output one line to tell if
there’s a moment that it’s possible for the thief to appear at any
cross. Look at the sample output for output format.
Sample Input
2
3 3 0
0 1
0 2
1 2
2 1 0
0 1
Sample Output
Case 1: YES
Case 2: NO
题意:一个小偷从初始点逃到他相邻的点,从某个点到另外若干个相邻的点的时间是相同的,
也就是同个时间点,问你在同个时间点小偷能否遍历全部点,能的话输出YES,否则输出NO。
解法:DFS判断连通性+DFS染色判断是否为二分图。
如果是个二分图那么它的奇数步和偶数步是属于各自独立的集合,
如果奇数步能够遍历到偶数步,这个意思就是此小偷可以在某个时间点遍历整个图的点。
画个奇数点的环,从某个点出发一点存在一条边,同时改变改点的奇偶性。
#include
using namespace
std;
const int maxn =
100010;
int V,E,S;
struct Edge
{
int v;
Edge* link;
}buffer[500010];
int tol;
Edge* node[maxn];
inline void
AddEdge(int u,int v)
{
Edge* tmp = &buffer[tol++];
tmp->v = v;
tmp->link = node[u];
node[u] = tmp;
}
class isBiGraph_Class
{
public:
int col[maxn]; //-1:白色
0:无色
1:黑色
bool DFS(int u,int
COL)
{
col[u] = COL;
int v;
Edge* tmp = node[u];
while(tmp)
{
v = tmp->v;
if(col[v]==0)
{
if(DFS(v,-COL) == 0)
return false;
}
else
if(col[v] ==
COL) //相邻的结点颜色相同,则不是二分图
return false;
tmp = tmp->link;
}
return true;
}
bool isBiGraph()
{
memset(col,0,sizeof(col));
for(int u=0; u
u++)
//可能有多个连通分支
if(col[u]
==0)
{
if(DFS(u,-1)==0)
return false;
}
return true;
}
}iBG;
bool vis[maxn];
int cnt;
void DFS(int
u)
{
vis[u] = 1;
cnt++;
Edge* tmp = node[u];
while(tmp)
{
if(!vis[tmp->v])
DFS(tmp->v);
tmp = tmp->link;
}
}
bool isLink()
{
cnt = 0;
memset(vis,0,sizeof(vis));
DFS(0);
if(cnt == V)
return true;
else
return false;
}
int main()
{
int T;
scanf("%d",&T);
for(int t=1; t<=T;
t++)
{
tol = 0;
scanf("%d%d%d",&V,&E,&S);
memset(node,0,sizeof(node));
int u,v;
while(E--)
{
scanf("%d%d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
if(isLink()
&& iBG.isBiGraph() ==
0)
printf("Case %d:
YES\n",t);
else
printf("Case %d:
NO\n",t);
}
return 0;
}