●BZOJ 1006 [HNOI2008]神奇的国度(弦图最小染色数)○ZOJ 1015 Fishing Net
●赘述题目
给出一张弦图,求其最小染色数。
●题解
网上的唯一“文献”:《弦图与区间图》(cdq),可以学习学习。(有的看不懂)
摘录几个解决改题所需的知识点:
●子图和诱导子图(一定要弄清楚)
子图:对于一个图G=(V,E) ,满足V'⊆V且E'⊆E的G’=(V',E')称为图G的子图
诱导子图:对于一个图G=(V,E),满足V'⊆V且E'=(所有(u,v)|u⊆V',v⊆V')的G'=(V',E')称为图G诱导子图
●团
若图G=(V,E)的一个子图G'=(V',E')是V'的完全图,则该子图G'称为一个团
●极大团
若一个团G'不是其他任何团的子图,则该团为极大图
●最大团
点数最多的团
●团数:
最大团的点数
●色数:
对图G进行染色,使得任何相邻的两点颜色不同,所需要的最少颜色数
一个性质:对于一个图G,满足团数≤色数
别人家的证明:因为团是完全图,一个n个点的完全图的色数为n,所以对于一个图的团数(极大团的点的个数)等于色数。
●弦:
连接环中的不相邻的两点的边

●弦图:一个无向图称为弦图当图中任意长度大于3的环都至少有一个弦
(即一个无向图不存在长度大于3的环则称为弦图)
一个性质:弦图的诱导子图也是弦图
另一个性质:弦图中,团数==色数
●单纯点:
对于一个点v,设n(v)表示与v相连的点集,若V'=v∪n(v)形成的诱导子图是一个团,则v是单纯点

●完美消除序列
一个点的序列(图的每个点出现一次):v1,v2,v3,...,vn,满足任意vi在{vi,vi+1,vi+2,...,vn}的诱导子图中是一个单纯点

●判断图G为弦图:ZOJ 1015 Fishing Net
MCS(最大势算法):
●用lab[ ]记录每个点的势(与多少标记的点相邻)
每次取出势最大的点(刚开始都为0),从后往前放入一个序列,并标记这个点为已标记,并更新与改点相连的点的势(+1),重复该操作,直到取完所有点。(用链表做到O(n(点数)+m(边数)))
●那么序列构造出来了,到底是不是完美消除序列呢(即是不是弦图)还需要check一下
check(优化后的,O(n+m)):
对于每个点vi,找出{vi,vi+1,vi+2,...,vn}中与它相连的点,并用vmin记录与它相连的点中在序列中位置最小的那个点,只需判断vmin是否和那些点相连,若没有连边,则不是完美消除序列,即不是弦图。
如果对于每个vi都成立,则是完美消除序列,即是弦图。
ZOJ 1015 代码(MCS判弦图):
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
struct edge{
int to,next;
}e[];
int head[],lab[],order[],g[][];
int n,m,ent=;
void add(int u,int v)
{
e[ent]=(edge){v,head[u]};head[u]=ent++;
e[ent]=(edge){u,head[v]};head[v]=ent++;
}
void msc()
{
bool vis[];
memset(vis,,sizeof(vis));
queue<int> link[];
int best=,u,v,cnt=n;
for(int i=;i<=n;i++) link[].push(i),lab[i]=;
while(!link[best].empty()||best)
{
if(link[best].empty()){best--; continue;}
u=link[best].front(); link[best].pop();
if(vis[u]) continue;
vis[u]=; order[u]=cnt--;
for(int i=head[u];i;i=e[i].next)
{
v=e[i].to;
if(vis[v]) continue;
lab[v]++; if(lab[v]>best) best=lab[v];
link[lab[v]].push(v);
}
}
}
bool check()
{
int p[],pnt,mi,ni;
for(int i=;i<=n;i++)
{
pnt=;mi=0x3f3f3f3f;
for(int j=head[i];j;j=e[j].next)
{
if(order[e[j].to]<order[i]) continue;
if(mi>order[e[j].to]) mi=order[e[j].to],ni=e[j].to;
p[++pnt]=e[j].to;
}
for(int j=;j<=pnt;j++)
{
if(p[j]==ni) continue;
if(!g[ni][p[j]]) return ;
}
}
return ;
}
void init()
{
memset(g,,sizeof(g));
memset(head,,sizeof(head));
ent=;
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n+m))
{
init();
for(int i=,a,b;i<=m;i++) scanf("%d%d",&a,&b),g[a][b]=g[b][a]=,add(a,b);
msc();
if(check()) printf("Perfect\n\n");
else printf("Imperfect\n\n");
}
return ;
}
那么对于BZOJ 1006这个题,已经告诉了我们,题目输入一个弦图,于是我们只需要用MCS求出完美消除序列,然后求团数(最大团点数):
因为在完美消除序列中的每个点vi,它在{vi,vi+1,vi+2,...,vn}形成的诱导子图中是单纯点,即我们找出在{vi,vi+1,vi+2,...,vn}中与vi相连的点,形成的点集V'=(那些点∪vi) 的诱导子图则是一个团,可以得出该团的点数,由此可以通过枚举vi找出团数(最大团点数)
BZOJ 1006 代码(n+m)
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct edge{
int to,next;
}e[];
int head[],rank[],sa[];
int n,m,ent=,ans;
void add(int u,int v)
{
e[ent]=(edge){v,head[u]};head[u]=ent++;
e[ent]=(edge){u,head[v]};head[v]=ent++;
}
void msc()
{
bool vis[]; int lab[];
memset(vis,,sizeof(vis));
queue<int> link[];
int best=,u,v,cnt=n;
for(int i=;i<=n;i++) link[].push(i),lab[i]=;
while(!link[best].empty()||best)
{
if(link[best].empty()){best--; continue;}
u=link[best].front(); link[best].pop();
if(vis[u]) continue;
vis[u]=; rank[u]=cnt; sa[cnt]=u; cnt--;
for(int i=head[u];i;i=e[i].next)
{
v=e[i].to;
if(vis[v]) continue;
lab[v]++; if(lab[v]>best) best=lab[v];
link[lab[v]].push(v);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=,a,b;i<=m;i++) scanf("%d%d",&a,&b),add(a,b);
msc();
for(int i=n,u,v,cnt;i>=;i--)
{
u=sa[i]; cnt=;
for(int j=head[u];j;j=e[j].next)
{
v=e[j].to; if(rank[v]<i) continue;
cnt++;
}
ans=max(ans,cnt);
}
printf("%d",ans);
return ;
}
时间复杂度分析:以上面程序的main( )里的求团数为例:
看似有两层循环,但我们来这么考虑:
第一层枚举了n个点;
两层循环全部结束后,每条边都被枚举了两次(2m)
所以总的复杂度为O(n+m)
●注:自学了一点皮毛,如果文中有问题,欢迎指出,谢谢。
●BZOJ 1006 [HNOI2008]神奇的国度(弦图最小染色数)○ZOJ 1015 Fishing Net的更多相关文章
- bzoj 1006: [HNOI2008]神奇的国度 弦图的染色问题&&弦图的完美消除序列
1006: [HNOI2008]神奇的国度 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1788 Solved: 775[Submit][Stat ...
- bzoj 1006: [HNOI2008]神奇的国度 -- 弦图(最大势算法)
1006: [HNOI2008]神奇的国度 Time Limit: 20 Sec Memory Limit: 162 MB Description K国是一个热衷三角形的国度,连人的交往也只喜欢三角 ...
- bzoj 1006 [HNOI2008]神奇的国度 弦图+完美消除序列+最大势算法
[HNOI2008]神奇的国度 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4370 Solved: 2041[Submit][Status][D ...
- [bzoj1006](HNOI2008)神奇的国度(弦图最小染色)【太难不会】
Description K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则. 他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关 ...
- BZOJ 1006: [HNOI2008]神奇的国度(弦图)
传送门 解题思路 弦图就是图中任意一个大小\(>=4\)的环至少存在一条两个节点不相邻的边,这样的图称为弦图,弦图有许多优美的性质.一个无向图是弦图当且仅当它有一个完美消除序列,完美消除序列就是 ...
- 【BZOJ】1006: [HNOI2008]神奇的国度 弦图消除完美序列问题
1006: [HNOI2008]神奇的国度 Description K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则. 他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的 ...
- [BZOJ 1006] [HNOI2008] 神奇的国度 【弦图最小染色】
题目链接: BZOJ - 1006 题目分析 这道题是一个弦图最小染色数的裸的模型. 弦图的最小染色求法,先求出弦图的完美消除序列(MCS算法),再按照完美消除序列,从后向前倒着,给每个点染能染的最小 ...
- BZOJ 1006 [HNOI2008] 神奇的国度(简单弦图的染色)
题目大意 K 国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即 AB 相互认识,BC 相互认识,CA 相互认识,是简洁高效的.为了巩固三角关系,K 国禁止四边关系,五边关系等 ...
- BZOJ 1006: [HNOI2008]神奇的国度( MCS )
弦图最小染色...先用MCS求出完美消除序列然后再暴力染色... ------------------------------------------------------------------- ...
随机推荐
- Bate敏捷冲刺每日报告--day5
1 团队介绍 团队组成: PM:齐爽爽(258) 小组成员:马帅(248),何健(267),蔡凯峰(285) Git链接:https://github.com/WHUSE2017/C-team 2 ...
- 卡尔曼滤波法C编程
float Angle = 0.0;//卡尔曼滤波器的输出值,最优估计的角度 //float Gyro_x = 0.0;//卡尔曼滤波器的输出值,最优估计的角速度 float Q_angle = 0. ...
- SpringBoot14 SpringBoot整合mybatis
1 版本说明 springboot:2.0 jdk:1.8 2 创建springBoot项目 创建项目时勾选必要web,MySQL,mybatis相关依赖 创建完成后再pom文件中添加自动部署.lom ...
- SpringCloud的应用发布(一)SpringCloud的样例工程
前言 这个综合例子创建了 6个微服务应用 一个服务注册中心 SvcReg(EurekaServer),生产中要考虑高可用 一个配置中心 CfgMgr + git目录存储配置(ConfigServer, ...
- Oracle update 执行更新操作后的数据恢复
操作数据库,经常会出现误操作,昨天执行的更新操作之后发现更新错了,只能想办法数据恢复了,现在整理一下 第一步:查询执行更新操作的时间 select r.FIRST_LOAD_TIME,r.* from ...
- multiprocessing.Process() ----------python中的多进程
python 当中 使用封装好的 multiprocessing 为我们实现创建多进程任务. 1 Process()方法创建子进程 使用multiprocessing.Process() 方法产生一个 ...
- Extensions in UWP Community Toolkit - SurfaceDialTextbox
概述 UWP Community Toolkit Extensions 中有一个为TextBox 提供的 SurfaceDial 扩展 - SurfaceDialTextbox,本篇我们结合代码详细讲 ...
- CentOS7 安装eclipse
1. 首先将eclipse的压缩包文件解压到/opt目录下,要使用root权限.执行如下解压命令:tar -zxvf eclipse-jee-oxygen-1a-linux-gtk-x86_64.ta ...
- 老男孩python学习之作业一购物小程序
想学编程由来已久 始终没有个结果,痛心不已 如今再次捡起来,望不负期望,不负岁月 ......一万字的废话...... 先介绍一下我的自学课程吧 "路飞学城"的<python ...
- webservice面试题
webservice是什么? 1.基于WEB的服务,服务端整出一些资源让客户端应用访问(提供数据) 2.webservice是一个跨语言跨平台的规范(抽象) 3.是多个跨语言跨平台的应用间通信整合的方 ...