1 条题解
-
0
自动搬运
来自洛谷,原作者为

kczno1
**搬运于
2025-08-24 21:46:22,当前版本为作者最后更新于2017-03-17 22:45:36,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
求弦图点色数。
考虑按完美消除序列从后往前,每个点贪心选择最小可染颜色,
那么他会产生的颜色种类<=所在团大小,
而一个团由于两两连边,每个点颜色都不同,所以产生的颜色种类>=团的大小,
所以弦图点色数就是弦图最大团的大小。
得到完美消除序列用最大势算法,每次选择与最多已选择点相连的点,
由于每次势最多+1,可以对每个值开个双向链表存势为该值的点,可以做到O(1)删除插入,
这样时间就是线性。
之后判断弦图就从后往前扫,检验x与相连的后面的点N(x)是否构成一个团,
就是先找到N(x)里最小的,之后检验他与N(x)其他点是否相连( 用hash表,bitset(压空间)存都是O(1)的 ),
如果不相连显然就不是团,如果相连,由于在他检验的时候已经保证N(x)是个团,那么加入一个和所有点都有连边的点显然还是一个团。
这样每条边只被枚举一次,也是线性的。
(当然这题不需要判断)
#include<cstdio> #define N 10010 #define M 1000100 int n,m,i,x,y,k; int t[N]; struct edge { int to,next; }l[M<<1];int e; void add_e(int x,int y) { l[++e]=(edge){y,t[x]};t[x]=e; } int next[N<<1],pre[N<<1]; int w[N],q[N],dy[N]; void push(int x) { pre[next[x]=next[N+w[x]]]=x; next[pre[x]=N+w[x]]=x; } void del(int x) { pre[next[x]]=pre[x];next[pre[x]]=next[x]; } int main() { freopen("1.in","r",stdin); scanf("%d%d",&n,&m); for(i=1;i<=m;++i) { scanf("%d%d",&x,&y); add_e(x,y);add_e(y,x); } for(i=1;i<=n;++i) push(i); int now=0,ans=0; for(k=n;k;--k,++now) { while(!next[N+now])--now; x=next[N+now]; del(x); q[k]=x;dy[x]=k; int sum=1; for(i=t[x];y=l[i].to;i=l[i].next) if(!dy[y]) { del(y); ++w[y]; push(y); } else ++sum; if(sum>ans)ans=sum; } printf("%d\n",ans); }
- 1
信息
- ID
- 2269
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者