• [BFS]JZOJ 4672 Graph Coloring


    Description

    现在你有一张无向图包含n个节点m条边。最初,每一条边都是蓝色或者红色。每一次你可以将一个节点连接的所有边变色(从红变蓝,蓝变红)。
    找到一种步数最小的方案,使得所有边的颜色相同。
     

    Input

    第一行包含两个数n,m(1<=n,m<=100000)分别代表节点数和边的数量
    接下来m行描述边,第i行ui,vi,ci,代表ui有一条颜色为ci的边与vi相连(ci是B或者是R),B代表蓝色,R代表红色。数据保证没有自环的边。

    Output

    如果没有方案就输出-1。否则第一行输出k代表最小的步数
     

    Sample Input

    输入1:
    3 3
    1 2 B
    3 1 R
    3 2 B
    
    
    
    输入3:
    4 5
    1 2 R
    1 3 R
    2 3 B
    3 4 B
    1 4 B

    Sample Output

    输出1:
    1
    
    
    输出3:
    -1
     

    Data Constraint

    对于30%数据,n<=20,m<=20

    分析

    非常简单的染色问题

    我们分两次BFS,一次选择把全部边变成红色,另一次显然

    然后一个点显然变两次是一样的,所以我们当边的颜色是否与当前选择的颜色不同给连接的点染色,若已染则判断是否相同或不同

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <memory.h>
    using namespace std;
    const int N=1e5+10;;
    struct Edge {
        int u,v,nx,type;
    }g[2*N];
    int cnt,list[N];
    int n,m; 
    bool b[N],vis[N];
    int ok,ans=2147483647,lans[2];
    
    void Add(int u,int v,char type) {
        g[++cnt]=(Edge){u,v,list[u],type=='R'?1:0};list[u]=cnt;
        g[++cnt]=(Edge){v,u,list[v],type=='R'?1:0};list[v]=cnt;
    }
    
    int BFS(int v0,int same) {
        queue<int> q;
        while (!q.empty()) q.pop();
        q.push(v0);vis[v0]=1;
        lans[1]++;
        while (!q.empty()) {
            int u=q.front();q.pop();
            for (int i=list[u];i;i=g[i].nx) {
                if (!vis[g[i].v]) {
                    b[g[i].v]=g[i].type==same?b[u]:(b[u]^1);
                    lans[b[u]^(g[i].type==same)]++;
                    q.push(g[i].v);
                    vis[g[i].v]=1;
                }
                else
                if (g[i].type==same&&b[u]!=b[g[i].v]||g[i].type!=same&&b[u]==b[g[i].v]) return -1;
            }
        }
        return min(lans[0],lans[1]);
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++) {
            int u,v;char c;
            scanf("%d%d",&u,&v);
            scanf("%c",&c);
            while (c!='R'&&c!='B') scanf("%c",&c);
            Add(u,v,c);
        }
        for (int i=0;i<2;i++) {
            bool p=1;int cans=0,nans=0;
            memset(b,0,sizeof b);memset(vis,0,sizeof vis);
            for (int j=1;j<=n;j++) if (!vis[j]) {
                lans[0]=lans[1]=0;
                cans=BFS(j,i);
                if (cans==-1) {
                    p=0;
                    break;
                }
                nans+=cans;
            }
            if (p) ans=min(ans,nans);
            ok+=p;
        }
        if (!ok) printf("-1");
        else printf("%d",ans);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    转:jQuery选择器大全(48个代码片段+21幅图演示)
    转:Web 开发中很实用的10个效果【附源码下载】
    转:在网站开发中很有用的8个 jQuery 效果【附源码】
    转:35个让人惊讶的 CSS3 动画效果演示
    转:总结const、readonly、static三者的区别
    转:C# 深入理解堆栈、堆在内存中的实现
    推荐:Asp.Net MVC 多语言(html+js共用一套资源文件)
    转:HttpModule与HttpHandler详解
    转: ASP.NET MVC 多语言配置
    spring集合类型注入
  • 原文地址:https://www.cnblogs.com/mastervan/p/10764860.html
Copyright © 2020-2023  润新知