您的位置:首页 > 其它

bzoj1006 神奇的国度【完美消除序列】

2017-12-17 22:05 351 查看

解题思路:

题目要求的就是用最少的颜色,使相连两点颜色不相同。

有结论如下:

最小染色数=最大团大小

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
,nxt[M],to[M],du
,q
;
bool exist
;
vector<int>g
;

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';
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: