弦图的判定MCS算法(zoj1015)
来源:互联网 发布:淘宝买产品送刀具骗法 编辑:程序博客网 时间:2024/04/29 18:27
题意:裸的弦图的判定:
弦图定义:给出一个无向连通图,如果每个环中都存在至少一条弦(环中存在不相邻的两点直接相连)这样的图叫做弦图;
转载:http://blog.csdn.net/crux_d/article/details/2251963
以下是时间复杂度为O(n+m)的算法,n是图的点数,m是图的边数。
第一步:给节点编号
设已编号的节点集合为A,未编号的节点集合为B
开始时A为空,B包含所有节点。
for num=n-1 downto 0 do
{
在B中找节点x,使与x相邻的在A集合中的节点数最多,将x编号为num,
并从B移入A
}
第二步:检查
for num=0 to n-1 do
{
对编号为num的节点x,设所有编号大于num且与x相邻的节点集合为C,
在集合C中找出编号最小的节点y,如果集合C中存在不等于y的节点z,
且y与z间没有边,则此图不是弦图,退出。
}
检查完了,则此图是弦图。
原始算法:
#include"stdio.h"#include"string.h"#include"stdlib.h"#include"queue"#include"algorithm"#include"string.h"#include"string"#include"math.h"#include"vector"#include"stack"#include"map"#define eps 1e-4#define inf 0x3f3f3f3f#define M 1209#define PI acos(-1.0)using namespace std;int cnt,vis[M],num[M],s[M],g[M][M];void bfs(int n){ int i,j,id; memset(vis,0,sizeof(vis)); memset(num,0,sizeof(num)); cnt=0; for(i=n;i>=1;i--) { id=1; for(j=1;j<=n;j++) { if(!vis[j]&&num[id]<num[j]) { id=j; } } s[i]=id; vis[id]=1; for(j=1;j<=n;j++) { if(id!=j&&g[id][j]&&!vis[j]) num[j]++; } }}int psq(int n){ int i,j; for(i=1;i<=n;i++) { int id; for(j=i+1;j<=n;j++) { if(g[s[i]][s[j]]) { id=j; break; } } for(j=i+1;j<=n;j++) { if(g[s[i]][s[j]]&&id!=j&&g[s[id]][s[j]]==0) return 0; } } return 1;}int main(){ int n,m,i; while(scanf("%d%d",&n,&m),m+n) { memset(g,0,sizeof(g)); for(i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); g[a][b]=g[b][a]=1; } bfs(n); if(psq(n)) { printf("Perfect\n\n"); } else printf("Imperfect\n\n"); } return 0;}bfs+优先队列
#include"stdio.h"#include"string.h"#include"stdlib.h"#include"queue"#include"algorithm"#include"string.h"#include"string"#include"math.h"#include"vector"#include"stack"#include"map"#define eps 1e-4#define inf 0x3f3f3f3f#define M 1009#define PI acos(-1.0)using namespace std;struct Edge{ int v; Edge(int vv) { v=vv; }};vector<Edge>edge[M];struct node{ int id,num; friend bool operator<(node a,node b) { return a.num<b.num; }};int n,num[M],vis[M],link[M],cnt,order[M],q[M],g[M][M];void bfs(int u){ priority_queue<node>q; memset(num,0,sizeof(num)); memset(link,0,sizeof(link)); memset(vis,0,sizeof(vis)); cnt=n; node now; now.id=u; now.num=1; q.push(now); while(!q.empty()) { node cur=q.top(); if(!vis[cur.id]) { vis[cur.id]=1; link[cnt]=cur.id; order[cur.id]=cnt; cnt--; if(cnt==0) break; } q.pop(); for(int i=0;i<(int)edge[cur.id].size();i++) { int v=edge[cur.id][i].v; num[v]++; now.id=v; now.num=num[v]; if(!vis[v]) q.push(now); } }}int check(){ int i,j,value; bfs(1); for(i=1;i<=n;i++) { int mini=n+1; int t=0; for(j=0;j<(int)edge[link[i]].size();j++) { int v=edge[link[i]][j].v; if(order[v]>i) { if(mini>order[v]) { mini=order[v]; value=v; } q[t++]=v; } } for(j=0;j<t;j++) { if(q[j]!=value&&g[value][q[j]]==0) return 0; } } return 1;}int main(){ int m,i,a,b; while(scanf("%d%d",&n,&m),m||n) { for(i=1;i<=n;i++) edge[i].clear(); memset(g,0,sizeof(g)); for(i=0;i<m;i++) { scanf("%d%d",&a,&b); edge[a].push_back(b); edge[b].push_back(a); g[a][b]=g[b][a]=1; } if(check()) printf("Perfect\n\n"); else printf("Imperfect\n\n"); }}
0 0
- 弦图的判定MCS算法(zoj1015)
- [弦图判定 完美消除序列 MCS算法] BZOJ 1242 Zju1015 Fishing Net弦图判定
- [ZOJ1015]Fishing Net 弦图判断
- [ZOJ1015]Fishing Net-弦图判断
- zoj1015
- BZOJ 1006 HNOI2008 神奇的国度 弦图最小染色 MCS算法
- BZOJ 1006 神奇的国度 弦图最小染色 MCS算法
- BZOJ1006 神奇的国度 【弦图染色——最大势算法MCS】
- 【算法】二分图的判定
- bzoj 1006: [HNOI2008]神奇的国度(弦图 MCS算法)
- 素数的Miller_Rabbin判定算法
- 交叉字符串的判定算法
- 算法复习-二部图判定 关节点判定(都用了DFS)
- 质数(素数)判定算法
- 经典算法问题 之 图的m-着色判定问题
- 判定T2 是不是T1 的子树(算法)
- 欧拉回路的判定(Fleury算法)
- 素数判定的一些讨论(Miller-Rabin算法)
- Andriod使用JNI调用OpenCV的C++接口(不用装OpenCVManager)
- Visual Studio 2010快捷键
- 【linux操作命令】mysql
- 仿函数
- 简单明了关键在谨记
- 弦图的判定MCS算法(zoj1015)
- linux编译多个源文件成同一个模块
- MyBatis3+SpringMVC3 - demo工程
- 安卓自带下拉刷新SwipeRefreshLayout添加上拉刷新功能
- 【141106noip训练】动态规划第三题:尼克的任务
- mysql用mongodb做缓存
- 如何查看windows和linux80端口号占用
- CareerCup 17中等难题 Q17.2 井字游戏
- connection.multi(); connection.exec();