这道题可以先看cdq神犇的论文。
用最大势算法来做,找到完美消除序列后,从后往前染色。
处理时用hash数组把当前需涂色的点的周围的点的颜色标记。
找到一个与周围都不同的颜色涂色,如果比当前最大颜色种类标号大,即替换。
#include <cstdio>
using namespace std;
const int N=10000;
int n,m,tot,ans;
int head[N+5],sh[N+5],q[N+5],hash[N+5],col[N+5];
bool vis[N+5];
struct edge{
int to;
int nxt;
}e[2000005];
inline void bui(int u,int v)
{
e[++tot].to=v;
e[tot].nxt=head[u];
head[u]=tot;
e[++tot].to=u;
e[tot].nxt=head[v];
head[v]=tot;
return ;
}
int main()
{
register int i,j;
scanf("%d %d",&n,&m);
for (i=1;i<=m;i++)
{
int u,v;
scanf("%d %d",&u,&v);
bui(u,v);
}
for (i=n;i;i--)
{
int t=0;
for (j=1;j<=n;j++)
if (!vis[j]&&sh[j]>=sh[t]) t=j;
vis[t]=1;q[i]=t;
for (j=head[t];j;j=e[j].nxt) sh[e[j].to]++;
}
for (i=n;i;i--)
{
int t=q[i];
for (j=head[t];j;j=e[j].nxt) hash[col[e[j].to]]=i;
for (j=1;;j++) if (hash[j]!=i) break;
col[t]=j;
if (j>ans) ans=j;
}
printf("%d",ans);
return 0;
}