[Bzoj1006][HNOI2008]神奇的国度

[Bzoj1006][HNOI2008]神奇的国度

标签: 弦图


题目链接

题意

给你一个弦图,对其进行染色,相邻的不能同色。
问最少多少种颜色

题解

cdq的论文《弦图与区间图》讲的很清楚了。
但是我还是来说一下吧。
一般图中满足
极大团大小<=色数。

然而在弦图中,
极大团大小=色数。
(因为弦图的极大团只有可能是某个点和在他完美消除序列后面且相邻的点 所形成的点集 的诱导子图至于为什么我不知道

所以直接在完美消除序列从后往前贪心取点就行了。

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
#define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
inline int read()
{
	int sum=0,p=1;char ch=getchar();
	while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
	if(ch=='-')p=-1,ch=getchar();
	while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
	return sum*p;
}

const int maxn=1e4+20;

struct node {
	int v,next;
};
node e[maxn*100*2];
int cnt,start[maxn];
int n,s[maxn],vis[maxn],id[maxn];

void addedge(int u,int v)
{
	e[++cnt]=(node){v,start[u]};
	start[u]=cnt;
}
int m;

void init()
{
	n=read();m=read();
	REP(i,1,m)
	{
		int u=read(),v=read();
		addedge(u,v);
		addedge(v,u);
	}
}

void doing()
{
	DREP(t,n,1)
	{
		int u=0;
		REP(i,1,n)if(!vis[i])
		{
			if(s[i]>s[u] || u==0)u=i;
		}
		vis[u]=t;id[t]=u;
		EREP(i,u)s[e[i].v]++;
	}
	int col[maxn]={0};
	DREP(i,n,1)
	{
		int u=id[i],color[maxn]={0};
		EREP(j,u)
		{
			color[col[e[j].v]]=1;
		}
		REP(j,1,n)if(!color[j]){col[u]=j;break;}
	}
	int ans=0;
	REP(i,1,n)ans=max(ans,col[i]);
	cout<<ans<<endl;
}

int main()
{
	init();
	doing();
	return 0;
}
posted @ 2017-09-05 10:52  Deadecho  阅读(301)  评论(0编辑  收藏  举报