【概述】

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 算法相关推荐

  1. 图论 —— 弦图 —— LexBFS 算法

    [概述] LexBFS 是字典序广度优先搜索(Lexicographic BFS),其常用于弦图的判定. 每次按从 n 到 1 的顺序依次给点编号,每个点维护一个 list,用于记录与其相邻的已标号点 ...

  2. 图论:关于弦图的几个图论结论

    定义 弦:连接环中不相邻的两个点的边 一个图是弦图当图中任意长度大于3的环都至少有一个弦. α(G):\alpha(G):α(G):图GGG中最大独立集的大小,称为最大独立集数 κ(G):\kappa ...

  3. 概率图模型-可分解图-连接树算法-弦图-图论

    概率图模型–精确推断算法的原理 本文主要内容 本文从可分解图出发,逐渐引入弦图,三角化图,然后揭示了为什么引入可分解图,因为可分解图是在连接树算法中最终得到的,还讲解了为什么要使用连接树算法,因为连接 ...

  4. neo4j python 算法_图论与图学习(二):图算法

    选自towardsdatascience 作者:Maël Fabien机器之心编译参与:熊猫 图(graph)近来正逐渐变成机器学习的一大核心领域,比如你可以通过预测潜在的连接来理解社交网络的结构.检 ...

  5. 图论算法 最短路程_图论与图学习(二):图算法

    选自towardsdatascience 作者:Maël Fabien 机器之心编译 参与:熊猫 图(graph)近来正逐渐变成机器学习的一大核心领域,比如你可以通过预测潜在的连接来理解社交网络的结构 ...

  6. 图论:弦图最小点染色

    弦图的定义:当图中任意长度大于3的环都至少有一个弦时, 一个无向图称为弦图 不存在四角.五角等关系就说明这个图是一个弦图 题目问的是,任何一对相互认识的人不可以组一队,问最多可以组多少对 所有的人构成 ...

  7. P3196 [HNOI2008]神奇的国度(弦图的最小染色问题)

    整理的算法模板合集: ACM模板 题目传送门 K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国 ...

  8. 无向图的完美消除序列 判断弦图 ZOJ 1015 Fish net

       ZOJ1015 题意简述:给定一个无向图,判断是否存在一个长度大于3的环路,且其上没有弦(连接环上不同两点的边且不在环上). 命题等价于该图是否存在完美消除序列. 所谓完美消除序列:在 vi,v ...

  9. ZOJ 1015 弦图判定

    一些定义: 弦图是一种特殊图:它的所有极小环都只有3个顶点. 单纯点:该顶点与其邻接点在原图中的导出子图是一个完全图. 图G的完美消去序列:一个顶点序列a1a2a3...an,使得对于每个元素ai,a ...

最新文章

  1. redis的7个应用场景
  2. 若依前后端分离版怎样修改主页面和浏览器上的图标和标题
  3. 去中心化多链钱包CoinU 30问(你想要的答案都在这里)
  4. Github标星5.4k+:常见NLP模型的代码实现(基于TensorFlow和PyTorch)
  5. C#报错:创建调试信息文件 ……obj\Debug\model.pdb: 拒绝访问
  6. Java微服务(四)【idea配置本地maven】【中文idea版本】(手把手编写,超级详细)
  7. 【简记】HTML CSS 的一些要点(不定时更新)
  8. 修改了WINCE自带的驱动程序后如何编译
  9. How to test software requirements specification (SRS)?
  10. MATLAB中exist函数的用法
  11. 人民大学的《统计学》
  12. SSM+汽车销售平台 毕业设计-附源码171619
  13. LE Coded PHY和LE Uncoded PHY
  14. 【WebLogic使用】3.WebLogic配置jndi数据源
  15. 白色网站,看久了不爽,segmentfault.com的夜色模式....
  16. 计算机法语怎么翻译软件,中法互译,好用的法语翻译软件
  17. Java如何计算年龄
  18. 详解Material Design体系组件
  19. mysql 查询当月当天数据量
  20. Qt 5.9.1 参考手册 QtTest 第5章 写一个基准线

热门文章

  1. three.js使用轨迹球控件TrackballControls控制相机(vue中使用three.js62)
  2. 程序员 笔记本 amd python_2019程序员笔记本推荐?
  3. redis客户端连接windows和linux下的redis 无法连接
  4. iOS不能跳转到支付宝的解决办法
  5. 3月9日云栖精选夜读:阿里聚安全 2016 年报
  6. OCR文字识别:深度学习算法识别步骤
  7. 施密特触发器原理图解详细分析
  8. 网络技术基础(五)*广域网接入技术
  9. 包装类的作用、拆箱/装箱实例演示和详细剖析
  10. 机器学习入门及基本算法图解