您的位置:首页 > 其它

[杂题]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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: