您的位置:首页 > 其它

【BZOJ】1006 神奇的国度

2016-01-29 18:44 387 查看

题目

BZOJ 1006 神奇的国度

分析

弦图,想到完美消除序列,首先用MCS算法求出来。

MCS算法:

http://wenku.baidu.com/view/6f9f2223dd36a32d73758126.html?re=view

http://tieba.baidu.com/p/2891159900

MCS写O(nlogn)O(n\log n)的算法就算了,O(n+m)O(n+m)的肯定会老是忘掉……

本图一定满足: 染色用的颜色数 ≤\leq 最大团的大小。

现在只用证明出这个极限即可,证明出这个极限的方法也可用于求染色用的最少颜色数。

我们从最后一个结点开始,每次找完美消除序列之后的所有不同颜色,将时间戳存到一个桶中。再遍历一遍桶,找出最小的没出现过的。

这样的算法就可以构造出答案。

代码

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;

const int N=10001;
const int M=1000001;

struct G
{
int v,nxt;
}map[M+M];
int tt,hd
;   //Graph
int lab
,tid
,seq
;
int color
,r
,colornum;
int n,m;
struct node
{
int w,id;
friend bool operator<(node a,node b)
{
return a.w<b.w;
}
};
priority_queue<node> q;

inline int read(void)
{
int s=0,f=1; char c=getchar();
for (;c<'0'||c>'9';c=getchar());
for (;'0'<=c&&c<='9';c=getchar()) s=s*10+c-48;
return s*f;
}

inline void ins(int u,int v)
{
map[++tt].v=v;
map[tt].nxt=hd[u];
hd[u]=tt;
}

void init_graph(void)
{
int x,y;
n=read(),m=read();
for (int i=1;i<=m;i++)
{
x=read(),y=read();
ins(x,y),ins(y,x);
}
}

void get_queue(void)
{
node t;
for (int i=1;i<=n;i++)
{
t.id=i,t.w=lab[i];
q.push(t);
}
for (int num=n;num>0;num--)
{
for (;!q.empty();)
{
t=q.top(),q.pop();
if (!tid[t.id]) break;
}
seq[num]=t.id,tid[t.id]=num;
for (int k=hd[t.id];k;k=map[k].nxt)
if (!tid[map[k].v])
{
lab[map[k].v]++;
t.id=map[k].v;
t.w=lab[map[k].v];
q.push(t);
}
}
}

void color_graph(void)
{
int now;
for (int num=n;num>0;num--)
{
now=seq[num];
for (int k=hd[now];k;k=map[k].nxt)
if (tid[map[k].v]>num) r[color[map[k].v]]=now;
int d=0;
for (int k=1;k<=colornum;k++)
if (r[k]^now)
{
color[now]=k;
d=1; break;
}
if (!d) color[now]=++colornum;
}
printf("%d\n",colornum);
}

int main(void)
{
init_graph();
get_queue();
color_graph();

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