hdu3478 Catch

 首先可以推断出图要是联通的并且要有奇数条边的回路才能输出YES,因为从一个点开始沿着一个环分别向左右两个方向遍历,只有当前环的结点数为奇数的时候左右两个方向到同一个点是一奇一偶的,
这样就说明存在某一时刻可以让贼出现在各个位置,因为这个点奇偶都可达,那么只需要进行一次BFS并且01染色就可以了
 #include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int size = 110000;
int color[size];//表示第i个点被染的颜色
int n, m;
vector <int> mapp[size];
queue <int> Que;
void init()
{
     for (int i = 0; i <= n; i ++){
         mapp[i].clear();   
     }    
}
bool bfs(int s)//从S点起开始查找当前图mapp中有无奇数条边的回路
{
     while (!Que.empty())Que.pop();
     Que.push(s);
     color[s] = 0;
     int num = 1;
     bool check = false;
     while (!Que.empty()){
           int pre = Que.front();
           Que.pop();
           for (int i = 0; i < mapp[pre].size(); i ++){
               int k = mapp[pre][i];
               if (color[pre] == color[k]){//如果前一个点后它的后继染色点相同则说明有奇数回路
                  check = true;
                  continue;             
               }   
               if (color[k] == -1){
                  num ++;
                  color[k] = color[pre]^1;
                  Que.push(k);            
               }
           }     
     }
     if (check && num == n)return true; //当前图是连通图且不能 构成二分图(存在奇数条边的回路)
     return false;
}
int main()
{
    int t;
    int s;
    scanf("%d", &t);
    int nc = 0;
    while (t --){
          init();
          scanf("%d%d%d", &n, &m, &s);
          while (m --){
                int a, b;
                scanf("%d%d", &a, &b);
                mapp[a].push_back(b);
                mapp[b].push_back(a);
          }
          memset(color, -1, sizeof(color));
          printf("Case %d: ", ++nc);
          bfs(s)?printf("YES\n"):printf("NO\n");
    }
    return 0;   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值