[Luogu3852][TJOI2007]小朋友

luogu

题意

求弦图的最大独立集。

sol

按照完美消除序列一个个贪心选即可。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
int gi()
{
	int x=0,w=1;char ch=getchar();
	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if (ch=='-') w=0,ch=getchar();
	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return w?x:-x;
}
const int N = 1e5+5;
int n,m,to[N],nxt[N],head[N],cnt,vis[N],seq[N],label[N],best,ans;
vector<int>v[N];
void link(int u,int v){to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;}
int main()
{
	n=gi();m=gi();
	for (int i=1;i<=m;++i)
	{
		int u=gi(),v=gi();
		link(u,v);link(v,u);
	}
	for (int i=1;i<=n;++i) v[0].push_back(i);
	for (int i=1,now;i<=n;++i)
	{
		bool fg=0;
		while (!fg)
		{
			for (int j=v[best].size()-1;j>=0;--j)
				if (!vis[v[best][j]]) {fg=1;now=v[best][j];break;}
				else v[best].pop_back();
			if (!fg) --best;
		}
		seq[i]=now;vis[now]=1;
		for (int e=head[now];e;e=nxt[e])
			if (!vis[to[e]])
			{
				v[++label[to[e]]].push_back(to[e]);
				best=max(best,label[to[e]]);
			}
	}
	memset(vis,0,sizeof(vis));
	for (int i=n;i;--i)
		if (!vis[seq[i]])
		{
			++ans;vis[seq[i]]=1;
			for (int e=head[seq[i]];e;e=nxt[e])
				vis[to[e]]=1;
		}
	printf("%d\n",ans);
	return 0;
}
posted @ 2018-04-04 14:10  租酥雨  阅读(317)  评论(0编辑  收藏  举报