题目大意就是给你一张弦图,问你色数。
弦图的色数等于团数。
我们可以用最大势算法(Maximum Cardinality Search)求出完美消除序列,然后贪心的倒序染最小的颜色,染的最大的颜色就是答案。
我这里直接认为就是label的最大值+1,不知道对不对,感觉没啥问题。如果有问题还请dalao指出,求轻虐。
具体有关弦图的理论可以看cdq在wc2009的论文:《弦图与区间图》
其实应该用链表来实现,不过用deque应该差不多吧,也是 O(n+m) 的
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define M 1000010
#define N 10010
inline char gc(){
static char buf[1<<16],*S,*T;
if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n,m,h[N],num=0,a[N],label[N],ans=0;
bool vis[N];
struct edge{
int to,next;
}data[M<<1];
inline void MCS(){
deque<int>q[N];int best=0;
for(int i=1;i<=n;++i) q[0].push_back(i);
for(int i=n;i>=1;--i){
int x=0;
while(1){
while(!q[best].empty()){
int y=q[best].front();q[best].pop_front();
if(!vis[y]){x=y;break;}
}if(x) break;--best;
}a[i]=x;vis[x]=1;ans=max(ans,label[x]);
for(int ii=h[x];ii;ii=data[ii].next){
int y=data[ii].to;if(vis[y]) continue;
label[y]++;q[label[y]].push_back(y);best=max(best,label[y]);
}
}
}
int main(){
// freopen("a.in","r",stdin);
n=read();m=read();
while(m--){
int x=read(),y=read();
data[++num].to=y;data[num].next=h[x];h[x]=num;
data[++num].to=x;data[num].next=h[y];h[y]=num;
}MCS();printf("%d\n",ans+1);
return 0;
}