图论 —— 弦图 —— MCS 算法
【概述】
MCS 算法是最大势算法(Maximum Cardinality Search),其常用于弦图的判定、求弦图的最大团、最小着色、最大独立集、最小团覆盖等。
一个无向图的弦图当且仅当其有一个完美消除序列,MCS 算法能够在 O(n+m) 内求出一个完美消除序列的反序。
每次执行 MCS 算法按从 n 到 1 的顺序依次给点标号,标号为 i 的点出现在完美消除序列的第 i 个,设 label[i] 为第 i 个点与多少个已标号点相邻,每次选择 label[i] 最大的未标号点进行标号,从而求一个完美消除序列的反序。
【算法核心】
vector<int> V[N];
void MCS() {for(int i=1; i<=n; i++)V[0].push_back(i);int maxx=0;int now=0;for(int i=1; i<=n; i++) { //从前往后bool flag=false;while(!flag) {for(int j=V[maxx].size()-1; j>=0; j--) { //从后往前if(vis[V[maxx][j]])V[maxx].pop_back();else {flag=true;now=V[maxx][j];break;}}if(!flag)maxx--;}vis[now]=true;//逆序存放order[n-i+1]=now;id[now]=n-i+1;for(int j=head[now]; j!=-1; j=edge[j].next) {int to=edge[j].to;if(!vis[to]) {label[to]++;V[label[to]].push_back(to);maxx=max(maxx,label[to]);}}}
}
【模版】
struct Edge {int to,next;Edge() {}Edge(int to,int next):to(to),next(next) {}
};
struct MCS{Edge edge[N<<1];int head[N],tot;int n,m;bool vis[N];int id[N];//编号int label[N];//与多少标号点相邻int order[N];//完美消除序列vector<int> V[N];void init(int n,int m) {this->n=n;this->m=m;for(int i=1; i<=n; i++)V[i].clear();memset(head,-1,sizeof(head));memset(order,0,sizeof(order));memset(label,0,sizeof(label));memset(vis,0,sizeof(vis));memset(id,0,sizeof(id));tot=0;}void addEdge(int x,int y) {edge[tot].to=y;edge[tot].next=head[x];head[x]=tot++;}void mcs() {for(int i=1; i<=n; i++)V[0].push_back(i);int maxx=0;int now=0;for(int i=1; i<=n; i++) { //从前往后bool flag=false;while(!flag) {for(int j=V[maxx].size()-1; j>=0; j--) { //从后往前if(vis[V[maxx][j]])V[maxx].pop_back();else {flag=true;now=V[maxx][j];break;}}if(!flag)maxx--;}vis[now]=true;//逆序存放order[n-i+1]=now;id[now]=n-i+1;for(int j=head[now]; j!=-1; j=edge[j].next) {int to=edge[j].to;if(!vis[to]) {label[to]++;V[label[to]].push_back(to);maxx=max(maxx,label[to]);}}}}int bucket[N];//桶int judge() { //判断是否是弦图memset(vis,0,sizeof(vis));memset(bucket,0,sizeof(bucket));for(int i=n; i>0; i--) {int cnt=0;int ret=1;for(int j=head[order[i]]; j!=-1; j=edge[j].next)if(id[edge[j].to]>i)vis[bucket[++cnt]=edge[j].to]=1;for(int j=head[bucket[1]]; j!=-1; j=edge[j].next) {int to=edge[j].to;if(to!=bucket[1]&&vis[to]) {if(vis[to]) {ret++;vis[to]++;}}}for(int j=1; j<=cnt; j++)vis[bucket[j]]=0;if(cnt&&ret!=cnt)return false;}return true;}int getMaximumClique() { //计算最大团、最小着色int res=0;for(int i=1; i<=n; i++)res=max(res,label[i]+1);return res;}int getMaximumIndependentSet() { //计算最大独立集、最小团覆盖memset(vis,0,sizeof(vis));int res=0;for(int i=1; i<=n; i++) {if(!vis[order[i]]) {res++;vis[order[i]]=true;for(int j=head[order[i]]; j!=-1; j=edge[j].next)vis[edge[j].to]=true;}}return res;}
}mcs;
int main() {int n,m;while(scanf("%d%d",&n,&m)!=EOF&&(n+m)) {mcs.init(n,m);for(int i=1; i<=m; i++) {int x,y;scanf("%d%d",&x,&y);mcs.addEdge(x,y);mcs.addEdge(y,x);}mcs.mcs();if(!mcs.judge())//若不为弦图printf("No\n");else { //若为弦图printf("Yes\n");int res1=mcs.getMaximumClique();//最大团、最小着色int res2=mcs.getMaximumIndependentSet();//最大独立集、最小团覆盖printf("The maximum clique:%d\n",res1);printf("The maximum independent set:%d\n",res2);}}return 0;
}
图论 —— 弦图 —— MCS 算法相关推荐
- 图论 —— 弦图 —— LexBFS 算法
[概述] LexBFS 是字典序广度优先搜索(Lexicographic BFS),其常用于弦图的判定. 每次按从 n 到 1 的顺序依次给点编号,每个点维护一个 list,用于记录与其相邻的已标号点 ...
- 图论:关于弦图的几个图论结论
定义 弦:连接环中不相邻的两个点的边 一个图是弦图当图中任意长度大于3的环都至少有一个弦. α(G):\alpha(G):α(G):图GGG中最大独立集的大小,称为最大独立集数 κ(G):\kappa ...
- 概率图模型-可分解图-连接树算法-弦图-图论
概率图模型–精确推断算法的原理 本文主要内容 本文从可分解图出发,逐渐引入弦图,三角化图,然后揭示了为什么引入可分解图,因为可分解图是在连接树算法中最终得到的,还讲解了为什么要使用连接树算法,因为连接 ...
- neo4j python 算法_图论与图学习(二):图算法
选自towardsdatascience 作者:Maël Fabien机器之心编译参与:熊猫 图(graph)近来正逐渐变成机器学习的一大核心领域,比如你可以通过预测潜在的连接来理解社交网络的结构.检 ...
- 图论算法 最短路程_图论与图学习(二):图算法
选自towardsdatascience 作者:Maël Fabien 机器之心编译 参与:熊猫 图(graph)近来正逐渐变成机器学习的一大核心领域,比如你可以通过预测潜在的连接来理解社交网络的结构 ...
- 图论:弦图最小点染色
弦图的定义:当图中任意长度大于3的环都至少有一个弦时, 一个无向图称为弦图 不存在四角.五角等关系就说明这个图是一个弦图 题目问的是,任何一对相互认识的人不可以组一队,问最多可以组多少对 所有的人构成 ...
- P3196 [HNOI2008]神奇的国度(弦图的最小染色问题)
整理的算法模板合集: ACM模板 题目传送门 K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国 ...
- 无向图的完美消除序列 判断弦图 ZOJ 1015 Fish net
ZOJ1015 题意简述:给定一个无向图,判断是否存在一个长度大于3的环路,且其上没有弦(连接环上不同两点的边且不在环上). 命题等价于该图是否存在完美消除序列. 所谓完美消除序列:在 vi,v ...
- ZOJ 1015 弦图判定
一些定义: 弦图是一种特殊图:它的所有极小环都只有3个顶点. 单纯点:该顶点与其邻接点在原图中的导出子图是一个完全图. 图G的完美消去序列:一个顶点序列a1a2a3...an,使得对于每个元素ai,a ...
最新文章
- redis的7个应用场景
- 若依前后端分离版怎样修改主页面和浏览器上的图标和标题
- 去中心化多链钱包CoinU 30问(你想要的答案都在这里)
- Github标星5.4k+:常见NLP模型的代码实现(基于TensorFlow和PyTorch)
- C#报错:创建调试信息文件 ……obj\Debug\model.pdb: 拒绝访问
- Java微服务(四)【idea配置本地maven】【中文idea版本】(手把手编写,超级详细)
- 【简记】HTML CSS 的一些要点(不定时更新)
- 修改了WINCE自带的驱动程序后如何编译
- How to test software requirements specification (SRS)?
- MATLAB中exist函数的用法
- 人民大学的《统计学》
- SSM+汽车销售平台 毕业设计-附源码171619
- LE Coded PHY和LE Uncoded PHY
- 【WebLogic使用】3.WebLogic配置jndi数据源
- 白色网站,看久了不爽,segmentfault.com的夜色模式....
- 计算机法语怎么翻译软件,中法互译,好用的法语翻译软件
- Java如何计算年龄
- 详解Material Design体系组件
- mysql 查询当月当天数据量
- Qt 5.9.1 参考手册 QtTest 第5章 写一个基准线
热门文章
- three.js使用轨迹球控件TrackballControls控制相机(vue中使用three.js62)
- 程序员 笔记本 amd python_2019程序员笔记本推荐?
- redis客户端连接windows和linux下的redis 无法连接
- iOS不能跳转到支付宝的解决办法
- 3月9日云栖精选夜读:阿里聚安全 2016 年报
- OCR文字识别:深度学习算法识别步骤
- 施密特触发器原理图解详细分析
- 网络技术基础(五)*广域网接入技术
- 包装类的作用、拆箱/装箱实例演示和详细剖析
- 机器学习入门及基本算法图解