题目大意:给定一个弦图,求最小染色
弦图相关问题,具体见陈丹琦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;
}