• jzoj 4672. 【NOIP2016提高A组模拟7.20】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

    Solution

    这题我们通过样例1可以发现:we need to 分类讨论
    因为如果单纯考虑全染成B的情况的话,答案就错了。
    于是分类讨论ing。。。
    由于图不一定完全联通,所以我们要枚举每个点
    然后,对于每一块,我们分类讨论,每个都得到了一个染色数目a,我们就将s+min(a,这一块的大小-a)。
    (PS:如果我们发现无法染成相同的话,就break掉即可)

    Code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 100010
    using namespace std;
    struct node{int v,fr,color;}e[N<<1];
    int n,m,c[N],tail[N],color,cnt=0,s,s1,s2,ans=100001;
    char ch;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    inline void add(int u,int v,int check) {e[++cnt]=(node){v,tail[u],check}; tail[u]=cnt;}
    
    void dfs(int x)
    {
    	if (c[x]) s1++; else s2++;
    	for (int p=tail[x],v,col;p;p=e[p].fr)
    	{
    		v=e[p].v,col=(c[x]+e[p].color+color) & 1;
    		if (c[v]==-1) c[v]=col,dfs(v);
    		else if (c[v]!=col) s=-1;
    		if (s==-1) return;
    	}
    }
    
    int main()
    {
    //	freopen("Graph Coloring.in","r",stdin);
    //	freopen("Graph Coloring.out","w",stdout);
    	n=read(),m=read();
    	for (int i=1,u,v;i<=m;i++)
    	{
    		u=read(),v=read(),ch=getchar();
    		add(u,v,ch=='R'),add(v,u,ch=='R');
    	}
    	for (color=0;color<=1;color++)
    	{
    		s=0;
    		memset(c,-1,sizeof(c));
    		for (int i=1;i<=n;i++)
    			if (c[i]==-1)
    			{
    				c[i]=1,s1=s2=0,dfs(i);
    				if (s==-1) break;
    				s+=std::min(s1,s2);
    			}
    		if (s!=-1) ans=std::min(s,ans);
    	}
    	if (ans==100001) puts("-1");
    	else printf("%d
    ",ans);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    javascript学习6
    javascript学习5
    javascript学习4
    javaccript学习3
    javaccript学习2
    javaccript学习1
    C++ 线性表实现
    深入解析策略模式(转)
    CentOS7安装MySQL
    万能媒体播放器 PotPlayer
  • 原文地址:https://www.cnblogs.com/jz929/p/11817544.html
Copyright © 2020-2023  润新知