[杂题]Codeforces 663C. Graph Coloring
2017-10-17 21:37
190 查看
Description
就是图上的开关灯游戏。每条边有一个颜色,每次选择一个点可以翻转一种颜色。
求使所有颜色相同的最小操作数。
Solution
枚举最后染成的颜色。如果一条边颜色与最后染成的颜色相同,那么它连接的两个点必须同时选或者同时不选。
那么只要dfs一次就好了。
有一个小坑(不过也是我太菜了啊QAQ)就是联通块要分开来算。。
#include <bits/stdc++.h> using namespace std; const int N = 101010; const int INF = 1 << 30; typedef long long ll; inline char get(void) { static char buf[100000], *S = buf, *T = buf; if (S == T) { T = (S = buf) + fread(buf, 1, 100000, stdin); if (S == T) return EOF; } return *S++; } template<typename T> inline void read(T &x) { static char c; x = 0; int sgn = 0; for (c = get(); c < '0' || c > '9'; c = get()) if (c == '-') sgn = 1; for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0'; if (sgn) x = -x; } inline char Get(void) { static char c; for (c = get(); c != 'R' && c != 'B'; c = get()); return c; } struct edge { int to, next, key; edge(int t = 0, int n = 0, int k = 0):to(t), next(n), key(k) {} }; edge G[N << 1]; int head ; int n, m, Gcnt, x, y, flag, f1, f2, cnt, Ans, clc, bl; int col , ans , vis , tmp , ans1 ; inline void AddEdge(int from, int to, int key) { G[++Gcnt] = edge(to, head[from], key); head[from] = Gcnt; G[++Gcnt] = edge(from, head[to], key); head[to] = Gcnt; } inline void dfs(int u, int f) { cnt += f; col[u] = f; ++bl; for (int i = head[u]; i; i = G[i].next) { if (col[G[i].to] == -1) dfs(G[i].to, f ^ G[i].key); else if (col[G[i].to] ^ f ^ G[i].key) flag = 1; } } inline void dfs1(int u, int v) { vis[u] = clc; ans[u] = col[u] ^ v; for (int i = head[u]; i; i = G[i].next) if (vis[G[i].to] != clc) dfs1(G[i].to, v); } int main(void) { read(n); read(m); for (int i = 0; i < m; i++) { read(x); read(y); if (Get() == 'R') AddEdge(x, y, 0); else AddEdge(x, y, 1); } Ans = INF; for (int i = 1; i <= n; i++) tmp[i] = INF; for (int i = 1; i <= n; i++) col[i] = -1; f1 = f2 = 0; for (int i = 1; i <= n; i++) if (col[i] == -1) { bl = flag = cnt = 0; dfs(i, 0); f1 |= flag; if (flag) break; if (cnt < tmp[i]) { ++clc; dfs1(i, 0); tmp[i] = cnt; } if (bl - cnt < tmp[i]) { ++clc; dfs1(i, 1); tmp[i] = bl - cnt; } } if (!f1) { Ans = 0; for (int i = 1; i <= n; i++) if (ans[i]) Ans++; for (int i = 1; i <= n; i++) ans1[i] = ans[i]; } for (int i = 1; i <= Gcnt; i++) G[i].key ^= 1; for (int i = 1; i <= n; i++) tmp[i] = INF; for (int i = 1; i <= n; i++) col[i] = -1; for (int i = 1; i <= n; i++) if (col[i] == -1) { bl = flag = cnt = 0; dfs(i, 0); f2 |= flag; if (flag) break; if (cnt < tmp[i]) { ++clc; dfs1(i, 0); tmp[i] = cnt; } if (bl - cnt < tmp[i]) { ++clc; dfs1(i, 1); tmp[i] = bl - cnt; } } if (f1 && f2) Ans = -1; else { cnt = 0; for (int i = 1; i <= n; i++) if (ans[i]) cnt++; if (cnt > Ans) for (int i = 1; i <= n; i++) ans[i] = ans1[i]; else Ans = cnt; } printf("%d\n", Ans); if (Ans > 0) for (int i = 1; i <= n; i++) if (ans[i]) printf("%d ", i); return 0; }
相关文章推荐
- CodeForces 706B Interesting drink (二分查找)
- codeforces 830E dp
- Codeforces 239D Boring Partition【思维】
- [Codeforces 940.E] Cashback(dp,数据结构,贪心)
- CodeForces 137A
- Codeforces 549F Yura and Developers
- CodeForces 706C Hard problem (水DP)
- 【Codeforces 808B】【容斥原理】Average Sleep Time 题解
- Codeforces-242C:King's Path(BFS+map)
- CodeForces - 924B Three-level Laser (二分搜索)
- codeforces 330A 330B 329A 分别是7月20DIV2的前三题
- Codeforces 551C GukiZ hates Boxes(二分)
- 【字典树】【贪心】Codeforces 706D Vasiliy's Multiset
- codeforces 811 E Vladik and Entertaining Flags(线段树+并查集)
- codeforces 746C 模拟
- CodeForces - 940B(模拟)
- CodeForces 154B——Colliders——筛选素数,模拟标记
- Codeforces 552E - Vanya and Brackets【表达式求值】
- Codeforces 706c dp
- CodeForces 811B Vladik and Complicated Book