首页 > 代码库 > BZOJ 1006 HNOI2008 神奇的国度 弦图最小染色 MCS算法

BZOJ 1006 HNOI2008 神奇的国度 弦图最小染色 MCS算法

题目大意:给定一个弦图,求最小染色

弦图相关问题,具体见陈丹琦09年讲稿《弦图与区间图》

PPT里有一个问题没说清楚 就是MCS算法的O(m+n)怎么来的 那个在 http://tieba.baidu.com/p/2891159900 有jcvb神犇详细的解答

至于染色如何标号,时间戳标记暴力硬扫即可

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 10100
using namespace std;
struct abcd{
	int to,next;
}table[4004004];
int head[M],tot;
int n,m,ans,best,f[M],list[M],seq[M],color[M],mark[M];
bool v[M];
void Add(int h[],int x,int y)
{
	table[++tot].to=y;
	table[tot].next=h[x];
	h[x]=tot;
}
void MCS()
{
	int i,j;
	for(i=1;i<=n;i++)
		Add(list,0,i);
	for(j=n;j;j--)
	{
		while(1)
		{
			for(i=list[best];i;i=table[i].next)
			{
				if(!v[table[i].to])
					break;
				else
					list[best]=table[i].next;
			}
			if(i)
			{
				int x=table[i].to;
				v[x]=1;seq[j]=x;
				for(i=head[x];i;i=table[i].next)
					if(!v[table[i].to])
					{
						f[table[i].to]++;
						Add(list,f[table[i].to],table[i].to);
						best=max(best,f[table[i].to]);
					}
				break;
			}
			else
				best--;
		}
	}
}
int main()
{
	int i,j,x,y;
	cin>>n>>m;
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		Add(head,x,y);
		Add(head,y,x);
	}
	MCS();
	for(j=n;j;j--)
	{
		x=seq[j];
		for(i=head[x];i;i=table[i].next)
			mark[ color[table[i].to] ]=j;
		for(i=1;i<=n&&mark[i]==j;i++);
		color[x]=i;
		ans=max(ans,i);
	}
	cout<<ans<<endl;
}


BZOJ 1006 HNOI2008 神奇的国度 弦图最小染色 MCS算法