题意:裸的弦图的判定:
弦图定义:给出一个无向连通图,如果每个环中都存在至少一条弦(环中存在不相邻的两点直接相连)这样的图叫做弦图;
转载: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"); } }