Codeforces 663C Graph Coloring(图染色dfs)

来源:互联网 发布:kali linux 切换xfce 编辑:程序博客网 时间:2024/05/29 08:33

题意:

给出一张图,每条边都有一个颜色(要么是红色要么是蓝色),如果翻转一个顶点,那么这个顶点相邻的边都会变色(红变蓝,蓝变红),求使得整个图变成同色的最小操作数,并且输出要翻转哪些顶点。


思路:最小操作数一定是全部变成红色和全部变成蓝色操作数的最小值,我们以全部变成红色举例:如果一条边是红色,那么这条边的两个顶点必然是:要么同时不翻转要么同时翻转,如果一条边是蓝色,那么这条边的两个顶点翻转的情况肯定是不一致的,我们不妨将翻转情况一致的放在同一个集合, 那么就会有两个集合,一个表示翻转的点一个表示不翻转的点。那么这个问题就变成图的染色问题,dfs或者bfs染色即可,因为集合可以通过翻转互补,一个连通块的最小操作数就是最小那个集合的尺寸。


代码:

#include <bits/stdc++.h>using namespace std;const int maxn = 1e5 + 5;struct Edge{    int to, col, next;}E[maxn << 1];int head[maxn];int vis[maxn], top, n, m;vector < int > g[2], st[2];int cnt=0; void add_edge(int u, int v, int col){    E[cnt].to = v;    E[cnt].col = col;    E[cnt].next = head[u];    head[u] = cnt++;} bool dfs(int u, int f, int col){ //f的取值为1表示翻,0表示不翻    vis[u] = f;    st[f].push_back(u);    for(int i = head[u]; ~i; i = E[i].next){        int v = E[i].to;        if(vis[v] != -1){            if((vis[u] ^ vis[v]) != (col ^ E[i].col))                return false;            continue;        }        if(!dfs(v, col ^ E[i].col ^ vis[u], col))            return false;    }    return true;} int solve(int col){    memset(vis, -1, sizeof vis);    for(int i = 1; i <= n; i++){        if(vis[i] == -1){            st[0].clear();            st[1].clear();            if(!dfs(i, 0, col)){                return n + 1;            }            int tmp = st[0].size() < st[1].size() ? 0 : 1;            g[col].insert(g[col].end(), st[tmp].begin(), st[tmp].end());        }    }    return g[col].size();} int main(){    int u, v;    char col;    scanf("%d%d", &n, &m);    memset(head, -1, sizeof head);    for(int i = 1; i <= m; i++){        scanf("%d %d %c", &u, &v, &col);        add_edge(u, v, col == 'R' ? 1 : 0);        add_edge(v, u, col == 'R' ? 1 : 0);    }    int sz0 = solve(0);    int sz1 = solve(1);    if(sz0 == n + 1 && sz1 == n + 1){        puts("-1");        return 0;    }    int tmp = sz0 < sz1 ? 0 : 1;    printf("%d\n", g[tmp].size());    for(int i = 0; i < g[tmp].size(); i++){        printf("%d ", g[tmp][i]);    }return 0;}

阅读全文
0 0