图的着色

我觉得既然你无法预料究竟要考什么那就在考到之前把oiwiki上的所有东西搬到你的博客里,这就是我现在正在做的。

点着色

(无自环无向图)

定义:对无向图的每个节点染\(k\)种颜色,使得相邻节点颜色不同,则该无向图是\(k-\)可染色的。若该图是\(k-\)可染色的,但不是\(k-1-\)可染色的,则\(k\)为该图\(G\)色数,记作\(\chi(G)\)

以下用\(\Delta(G)\)表示\(G\)中所有节点的最大度数。对任意图,\(\chi(G)\le\Delta(G)+1\)。特别的,对于二分图,\(\chi(G)=2\)(显然)。

Brook定理

设连通图不是完全图也不是奇环,则\(\chi(G)\le\Delta(G)\)

四色定理

任意平面图都是\(4-\)可染色的。

Welsh—Powell 算法

一个基于贪心求解图染色方案的算法,要求不限制最大着色数。过程大概是:

  1. 降序按所有点的度数把点排序。
  2. 将第一个点染成一个未被使用的颜色。
  3. 顺次遍历接下来的点,若当前点和所有与第一个点颜色相同的点不相邻,则将该点染成与第一个点相同的颜色。
  4. 返回第一步。
    显然它是\(O(n^2)\)的。啥你问我有最大限制?建议爆搜。

这代码我还用上吗(口胡了一份应该没什么问题,有问题私我

bool cmp(int a,int b){
	return deg[a]>deg[b];
}
void getcolor(){
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++){
		if(!col[i]){
			col[i]=++cnt;
			for(int j=i;j<=n;j++){
				bool jud=false;
				for(int k=head[j];k;k=edge[k].next){
					if(col[edge[i].v]==cnt){
						jud=true;break;
					}
				}
				if(!jud)col[j]=cnt;
			}
		}
	}
}

边着色

类似点着色,对所有边染\(k\)种色,有公共节点的边不能染一种色,则该图是\(k-\)边可着色的。色数的定义同上。

Vizing 定理

\(G\)是简单图,则\(\Delta(G)\le \chi(G)\le\Delta(G)+1\)。特别的,对于二分图,有\(\Delta(G)=\chi(G)\)

\(n\)阶完全图\(K_n\),当\(n\)为奇数时\(\chi(K_n)=n\),为偶数时\(\chi(K_n)=n-1\)

这个有的时候有用。

给定一张二分图,左侧有\(n\)个点,编号为\(1\)\(n\),右侧有\(m\)个点,编号为\(1\)\(m\),有\(k\)条无向边。

给定\(c\),你需要将每条边染色为\([1,c]\)中的一种颜色。现在,对于第\(i\)个点,我们定义它的代价为与\(i\)点相连的边中,出现最多的颜色数减去出现最少的颜色数(如果一种颜色没有出现,我们认为它的出现次数为\(0\))。

你需要构造一种方案,使得每个点的代价和最小,输出代价和方案。

首先根据Vizing定理可以知道这个最小的代价和是度数不为\(c\)倍数的点的个数。接下来考虑如何构造这个方案。

首先拆点,对于度数为\(c\)倍数的点,拆成若干度数为\(c\)的点。对于其余的点,拆成若干度数为\(c\)倍数的点和一个度数为除以\(c\)的余数的点。边连的点任意。

加入一条边\((x,y)\)时,尝试找到编号最小的没有被两个节点使用的颜色\(col_x,col_y\)。若相等则直接染色。

否则假设\(col_x<col_y\)。从\(y\)开始找到颜色依次为\(col_x,col_y,col_x\cdots\)的一条增广路,把它们的颜色反色(即\(col_x\)变为\(col_y\)\(col_y\)变为\(col_x\))。然后将该边染为\(col_x\)

色多项式到时候再说。

posted @ 2022-09-03 19:29  gtm1514  阅读(187)  评论(0编辑  收藏  举报