解题思路:
题目要求的就是用最少的颜色,使相连两点颜色不相同。
有结论如下:
最小染色数=最大团大小
Proof.
不可能比这个更小,只需证这个是可行的。考虑按完美消除序列倒序把所有点加进来,每个点只需和所有当前相邻的点不同颜色即可,而当前所有相邻的点最大是最大团大小。
所以只需用最大势算法求出完美消除序列,倒着加点统计即可。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#define ll long long
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-')f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=10005,M=2000005;
int n,m,mx,ans;
int tot,first[N],nxt[M],to[M],du[N],q[N];
bool exist[N];
vector<int>g[N];
void add(int x,int y)
{
nxt[++tot]=first[x],first[x]=tot,to[tot]=y;
}
void create()
{
for(int i=n;i;i--)
{
int e=first[mx];
while(exist[to[e]])
{
first[mx]=e=nxt[e];
while(!e)e=first[--mx];
}
first[mx]=nxt[e];
while(!first[mx])mx--;
int u=to[e];
q[i]=u,exist[u]=1;
for(e=0;e<g[u].size();e++)
{
int v=g[u][e];
if(exist[v])continue;
++du[v];add(du[v],v);
if(du[v]>mx)mx=du[v];
}
}
}
void solve()
{
memset(exist,0,sizeof(exist));
for(int i=n;i;i--)
{
int u=q[i],cnt=1;exist[u]=1;
for(int e=0;e<g[u].size();e++)
if(exist[g[u][e]])cnt++;
ans=max(ans,cnt);
}
}
int main()
{
//freopen("lx.in","r",stdin);
n=getint(),m=getint();
for(int i=1;i<=n;i++)add(0,i);
while(m--)
{
int x=getint(),y=getint();
g[x].push_back(y),g[y].push_back(x);
}
create();
solve();
cout<<ans<<'\n';
}