CodeForces 624C【二分图染色】

来源:互联网 发布:linux怎么进入编辑 编辑:程序博客网 时间:2024/05/29 11:43

题意:
本来有一个由’a’,’b’,’c’ 组成的字符串,然后,在这个串里,相同字符 或者 相邻字符能构成边,然后就构成了一副图。
现在抹掉了这个字符串,给你这副图,问你能不能组成这个字符串。

思路:
其实重要的就是:如果存在两个点没有边,这两个点只能是 a,c;
那么问题变成,给我这副图的补图是不是能由 a, c 组成,边的相邻两点只能是 a-c;
那么就用染色可以简单地解决这个问题。
补图可能存在多个连通块,而且求出的补图可能使得原图不符,所以还要判断构造出来的原图是否满足;
最后按照构造好的输出。

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int M = 5e5+10;const int N = 5e2+10;struct Edge{    int v;    int nex;}edge[M];int head[N], tol;int n,m;void init(){    tol = 0;    memset(head, -1, sizeof(head));}void add(int u, int v){    edge[tol].v = v;    edge[tol].nex = head[u];    head[u] = tol++;}bool flag;int col[N];void DFS(int u){    if(!flag) return;    for(int i=head[u];~i;i=edge[i].nex){        int v = edge[i].v;        if(col[v] == -1){            col[v] = 1 - col[u];            DFS(v);        }        else{            if(col[v] == col[u]){                flag = false;                return;            }        }    }}bool vis[N];int ma[N][N];int main(){    int u, v;    scanf("%d%d", &n, &m);    memset(ma, 0, sizeof(ma));    while(m--){        scanf("%d%d", &u, &v);        ma[u][v] = ma[v][u] = 1;    }    init();    memset(vis, false, sizeof(vis));    for(int i=1;i<=n;i++){        for(int j=1;j<=n;j++){            if(i == j) continue;            if(!ma[i][j]){                vis[i] = vis[j] = true;                add(i, j);            }        }    }    flag = true;    memset(col, -1, sizeof(col));    for(int i=1;i<=n;i++){        if(col[i] != -1 || !vis[i]) continue;        col[i] = 1;        DFS(i);        if(!flag){            puts("No");            return 0;        }    }    for(int i=1;i<=n;i++){        for(int j=1;j<=n;j++){            if(i == j) continue;            if(ma[i][j]){                if((col[i] == 1 && col[j] == 0) || (col[i] == 0 && col[j] == 1)){                    puts("No");                    return 0;                }            }        }    }    puts("Yes");    for(int i=1;i<=n;i++){        if(col[i] == 1) printf("a");        else if(!col[i]) printf("c");        else printf("b");    }    return 0;}/*4 41 21 31 43 46 11 1 21 31 5 1 4 1 62 5 2 63 4 3 65 64 6 3 62 61 4 1 21 31 62 43 54 66 5 */