[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 }