zoukankan      html  css  js  c++  java
  • CF600F Edge coloring of bipartite graph

    一、题目

    点此看题

    二、解法

    ( t vizing) 定理板题,可以去看看 oiwiki

    当然我不会证这个定理,我只会给出二分图背景下这个定理的构造性证明。

    结论:二分图的边染色最小颜色数是点的最大度数

    考虑增量法构造,现在考虑边 ((x,y)) 的染色,设点 (x) 未使用的最小颜色是 (lx),设点 (y) 未使用的最小颜色是 (ly),如果 (lx=ly) 那么直接把这条边染色成 (lx);否则从 (y) 开始找到一条 (lx,ly,lx...) 的"增广路",把这一条增广路上所有边的"反转"即可。

    这种做法的正确性来源于增广路径不自交,因为除 (x) 以外的点都把 (lx,ly) 的边拿去增广了,以后的增广不会有这种颜色的边连进来,又因为 (lx)(x) 未使用过的最小颜色,所以路径不会回到 (x),这也说明了增广路径是有限的。

    因为每次取的是最小的未使用颜色,所以所有边的颜色都不超过最大度数。

    三、应用

    给你一张左部 (n) 个点、右部 (m) 个点的二分图,给每条边染 ([1,c]) 中的某一种颜色,定义一个点的权值为出现次数的最大值减去出现次数的最小值,试构造方案使得最后总权值最小。

    答案下界是 (sum[d_imod c ot=0]),可以应用上述方法证明它,对于所有度数 (geq c) 的节点,我们对它做拆点,也就是任取 (c) 条边连在这个节点上,然后把这些边在原节点上删去,这样最后剩下的二分图最大度数一定 (leq c),可以对它做边染色。

    拆出来的点一定拥有 ([1,c]) 中的所有颜色,原来的点会产生 (1) 的贡献,易知达到了答案下界,构造方案只需要记录每个点属于原先的哪个节点,然后把边染色对应上去即可。

    四、总结

    二分图中增广的思想特别重要,找有特殊性质(如最小值最大值)的元素构造的思想也值得借鉴。

    #include <cstdio>
    #include <iostream>
    using namespace std;
    const int M = 100005;
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int n,m,k,t,a[M],b[M],d[M],f[2005][1005];
    void dfs(int u,int v,int x,int y)
    {
    	int to=f[v][x];
    	f[u][x]=v;
    	f[v][x]=u;
    	if(!to)
    	{
    		f[v][y]=0;
    		return ;
    	}
    	dfs(v,to,y,x);
    }
    signed main()
    {
    	n=read();m=read();k=read();
    	for(int i=1;i<=k;i++)
    	{
    		a[i]=read();b[i]=n+read();
    		d[a[i]]++;d[b[i]]++;
    	}n+=m;
    	for(int i=1;i<=n;i++) t=max(t,d[i]);
    	for(int i=1;i<=k;i++)
    	{
    		int lx=1,ly=1;
    		while(f[a[i]][lx]) lx++;
    		while(f[b[i]][ly]) ly++;
    		if(lx==ly)
    		{
    			f[a[i]][lx]=b[i];
    			f[b[i]][lx]=a[i];
    			continue;
    		}
    		dfs(a[i],b[i],lx,ly);
    	}
    	printf("%d
    ",t);
    	for(int i=1;i<=k;i++)
    		for(int j=1;j<=t;j++)
    			if(f[a[i]][j]==b[i])
    			{
    				printf("%d ",j);
    				break;
    			}
    }
    
  • 相关阅读:
    mysql 查看存储过程 并导出
    mysql 添加记录或者删除记录
    mysql 修改表的字段
    搭建docker私有仓库
    安装gitlab并配置邮箱
    Mac 安装MySQL-python
    android studio 调试安装
    给定日期求星期几
    数字三角形
    程序设计实训-课程表管理系统项目中遇到的问题
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/15225099.html
Copyright © 2011-2022 走看看