【Codeforces542E】Playing on Graph [Bfs][Dfs]
Playing on Graph
Time Limit: 20 Sec Memory Limit: 512 MBDescription
Input
Output
Sample Input
5 4
1 2
2 3
3 4
3 5
1 2
2 3
3 4
3 5
Sample Output
3
HINT
n <= 1000, m <= 10^5
Solution
我们先考虑无解的情况。显然就是图中有奇环的时候无解,因为你将奇环上两点缩起来,最后必定会变成一个三元环,而三元环是不能合并的。所以就可以Dfs黑白染色一下,若是搜到两个同色的话即是有奇环。
我们再考虑如何构造一种方案,显然,我们先找出一个点root,然后将所有 dist 相同的并起来,这样是一组可行解。可以发现,所有的方案都可以由这种方式构造出来。
那么这时候,确定一点 为 root 的时候,贡献显然等于最大的 dist。那么我们将所有点都确定为root一遍,然后Bfs求一下dist,取出最大dist,就可以得到一个联通块的答案了。
显然可以有多个连通块,Ans = Σ每个连通块的答案。
Code
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 using namespace std; 9 typedef long long s64; 10 11 const int ONE = 800005; 12 const int Base = 2005; 13 14 int n, m; 15 int x, y; 16 int next[ONE], first[ONE], go[ONE], tot; 17 int vis[ONE], col[ONE]; 18 int pd; 19 int vis_a[ONE], record[ONE], num, dist[ONE]; 20 int Ans; 21 queue <int> q; 22 23 int get() 24 { 25 int res;char c; 26 while( (c=getchar())<48 || c>57 ); 27 res=c-48; 28 while( (c=getchar())>=48 && c<=57 ) 29 res=res*10+c-48; 30 return res; 31 } 32 33 void Add(int u, int v) 34 { 35 next[++tot] = first[u], first[u] = tot, go[tot] = v; 36 next[++tot] = first[v], first[v] = tot, go[tot] = u; 37 } 38 39 void Dfs(int u, int color) 40 { 41 vis[u] = 1; 42 col[u] = color; 43 record[++num] = u; 44 for(int e = first[u]; e; e = next[e]) 45 { 46 int v = go[e]; 47 if(!vis[v]) Dfs(v, color ^ 1); 48 else pd |= col[v] == col[u]; 49 } 50 } 51 52 int Bfs(int S) 53 { 54 for(int i = 1; i <= n; i++) dist[i] = vis_a[i] = 0; 55 dist[S] = 0, vis_a[S] = 1, q.push(S); 56 while(!q.empty()) 57 { 58 int u = q.front(); q.pop(); 59 for(int e = first[u]; e; e = next[e]) 60 { 61 int v = go[e]; 62 if(vis_a[v]) continue; 63 vis_a[v] = 1; 64 dist[v] = dist[u] + 1; 65 q.push(v); 66 } 67 } 68 69 int res = 0; 70 for(int i = 1; i <= n; i++) 71 res = max(res, dist[i]); 72 return res; 73 } 74 75 int main() 76 { 77 n = get(); m = get(); 78 for(int i = 1; i <= m; i++) 79 { 80 x = get(), y = get(); 81 Add(x, y); 82 } 83 84 for(int i = 1; i <= n; i++) 85 if(!vis[i]) 86 { 87 num = 0; 88 Dfs(i, 0); 89 if(pd == 1) {printf("-1"); return 0;} 90 91 int res = 0; 92 for(int j = 1; j <= num; j++) 93 res = max(res, Bfs(record[j])); 94 Ans += res; 95 } 96 97 printf("%d", Ans); 98 }
un[ʌn]
- n. (Un)人名;(柬)温
- pron. 家伙,东西