HDU-3478 Catch

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3478

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

Hint

For the first case, just look at the table below. (YES means the thief may appear at the cross at that moment)

For the second input, at any moment, there’s at least one cross that the thief can’t reach.

题目分析:

          题目大概意思是,有n个点,m条边。罪犯可以从a点到达b点的条件是a,b有边相连,那么如果每一次他都不停止运动,他有没有可能在一个时间点到达任意一个点。既然是要在任意时间点达到任意一个点,首先需要保证这是一个连通图。这里,连通图的判断通过并查集得到。对于并查集比较形象的解释可以参考下https://www.cnblogs.com/-new/p/6662301.html。保证了连通图,我们再来思考如何保证可以到达任意一个点。

          小偷的逃跑路线其实是一个二分图的A部到B部,如果不是一个二分图,那么小偷就能通过奇数环(二分图的环都是偶环),让两部的点混合导致可以同时出现。所以只要满足不是二分图且连通,就输出Yes。

         

#include<stdio.h>
#include<queue>
#include<vector>
using namespace std;
vector<int >map[100050];
int f[100050];
int color[100050];
int n,m,s;
int find(int a)
{
    int r=a;
    while(f[r]!=r)
    r=f[r];
    int i=a;
    int j;
    while(i!=r)
    {
        j=f[i];
        f[i]=r;
        i=j;
    }
    return r;
}
void merge(int a,int b)
{
    int A,B;
    A=find(a);
    B=find(b);
    if(A!=B)
    f[B]=A;
}
int bfs(int x)
{
    queue<int >s;
    s.push(x);
    color[x]=1;
    while(!s.empty())
    {
        int u=s.front();
        s.pop();
        for(int i=0;i<map[u].size();i++)
        {
            int v=map[u][i];
            if(color[v])
            {
                if(color[v]==color[u])return 0;
            }
            else
            {
                color[v]=3-color[u];
                s.push(v);
            }
        }
    }
    return 1;
}
int main()
{
    int t;
    int kase=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&s);
        for(int i=0;i<=n;i++)
        {
            color[i]=0;
            f[i]=i;
            map[i].clear();
        }
        for(int i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            map[x].push_back(y);
            map[y].push_back(x);
            merge(x,y);
        }
        int cont=0;
        for(int i=0;i<n;i++)
        {
            if(f[i]==i)cont++;
        }
        if(cont==1)
        {
            int tmp=bfs(s);
            if(tmp==0)
            {
                printf("Case %d: YES\n",++kase);
            }
            else
            {
                printf("Case %d: NO\n",++kase);
            }
        }
        else
        {
            printf("Case %d: NO\n",++kase);
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值