[HDOJ3478]Catch

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3478

 

题目可以抽象成判断给的图是否是二分图,如果是则不满足条件,不是则满足。前提是图是个连通图,因此要额外判断此图是否联通。用染色法判断是否是二分图,注意点的数量太多,用邻接表存。可以用并查集判断是否联通。

给定初始点,因此BFS做会好思考一些。

注意输出结果全部大写。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <map>
 18 #include <cmath>
 19 
 20 using namespace std;
 21 
 22 const int maxn = 100010;
 23 vector<int> G[maxn];
 24 int n, m, s;
 25 int color[maxn];
 26 int pre[maxn];
 27 int vis[maxn];
 28 queue<int> q;
 29 
 30 int find(int x) {
 31     return x == pre[x] ? x : pre[x] = find(pre[x]);
 32 }
 33 
 34 void unite(int x, int y) {
 35     x = find(x);
 36     y = find(y);
 37     if(x != y) {
 38         pre[y] = x;
 39     }
 40 }
 41 
 42 inline void init() {
 43     for(int i = 0; i < maxn; i++) {
 44         pre[i] = i;
 45     }
 46 }
 47 
 48 bool bfs() {
 49     while(!q.empty()) {
 50         q.pop();
 51     }
 52     memset(color, -1, sizeof(color));
 53     color[s] = 0;
 54     q.push(s);
 55     while(!q.empty()) {
 56         int now = q.front();
 57         q.pop();
 58         for(int i = 0; i < G[now].size(); i++) {
 59             if(color[G[now][i]] == -1) {
 60                 color[G[now][i]] = color[now] ^ 1;
 61                 q.push(G[now][i]);
 62             }
 63             else {
 64                 if(color[G[now][i]] == color[now]) {
 65                     return false;
 66                 }
 67             }
 68         }
 69     }
 70     return true;
 71 }
 72 
 73 int main() {
 74     int kase = 1;
 75     int T, a, b;
 76     // freopen("in", "r", stdin);
 77     scanf("%d", &T);
 78     while(T--) {
 79         memset(vis, 0, sizeof(vis));
 80         int flag = 0;
 81         init();
 82         scanf("%d %d %d", &n, &m, &s);
 83         for(int i = 0; i <= n; i++) {
 84             G[i].clear();
 85         }
 86         for(int i = 0; i < m; i++) {
 87             scanf("%d %d", &a, &b);
 88             G[a].push_back(b);
 89             G[b].push_back(a);
 90             vis[a] = 1;
 91             vis[b] = 1;
 92             unite(a, b);
 93         }
 94         int tmp;
 95         for(int i = 0; i < m; i++) {
 96             if(vis[i]) {
 97                 tmp = pre[i];
 98                 break;
 99             }
100         }
101         for(int i = 0; i < m; i++) {
102             if(vis[i]) {
103                 if(tmp != pre[i]) {
104                     flag = 1;
105                     break;
106                 }
107             }
108         }
109         if(flag) {
110             printf("Case %d: NO\n", kase++);    
111         }
112         else {
113             if(bfs()) {    //是二分图
114                 printf("Case %d: NO\n", kase++);    
115             }
116             else {
117                 printf("Case %d: YES\n", kase++);
118             }
119         }
120     }
121 }

 

posted @ 2015-09-07 22:02  Kirai  阅读(166)  评论(0编辑  收藏  举报