hdu 3478 Catch

来源:互联网 发布:云杉网络 张天鹏 编辑:程序博客网 时间:2024/05/21 14:46

题目大概意思是,有n个点,m条边。罪犯可以从a点到达b点的条件是a,b有边相连,那么如果每一次他都不停止运动,他有没有可能在一个时间点到达任意一个点。

我们先bfs一遍,然后把他奇数时间能到达的点标记为1,偶数时间能到达的点标记为 0。这样标记之后,我们要做的是看能不能得到一个二部图。

如果在同为标记为1或0的集合中存在两个点有边相连,那么就说明他不是一个二部图,也就是在某个奇数时间能到达该点,在某个偶数时间也能到达该点,这样回溯回去的话,就可能在一个时间到达任意一个点。

#include <iostream>#include<cstdio>#include<vector>#include<cstring>#include<queue>using namespace std;vector<int>v[100010];int even_odd[100010]; //在奇数时间访问到标记为1,偶数时间访问到标记为0int n,m,s;queue<int>q;bool bfs(){    while(!q.empty())    {        int cur = q.front();        q.pop();        for(int i = 0; i< v[cur].size(); i++)        {            int temp = v[cur].at(i);            if(even_odd[temp] == -1)            {                even_odd[temp] = even_odd[cur] ^ 1;                q.push(temp);            }            else if(even_odd[temp] == even_odd[cur])                return true;        }     }    return false;}int main(){    int cas = 1;    int t;    scanf("%d",&t);    while(t--)    {        ans = 1;        scanf("%d %d %d",&n,&m,&s);        memset(even_odd,-1,sizeof(even_odd));        for(int i = 0 ; i < n; i++)            v[i].clear();        while(!q.empty())            q.pop();        for(int i = 0 ; i < m; i++)        {            int a,b;            scanf("%d %d",&a,&b);            v[a].push_back(b);            v[b].push_back(a);        }        even_odd[s] = 0;  //起始点标记为0        q.push(s);        printf("Case %d: ",cas++);        if(bfs()) printf("YES\n");        else printf("NO\n");    }    return 0;}


0 0
原创粉丝点击