弦图的判定MCS算法(zoj1015)

题意:裸的弦图的判定:

弦图定义:给出一个无向连通图,如果每个环中都存在至少一条弦(环中存在不相邻的两点直接相连)这样的图叫做弦图;

转载: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");
    }
}



你可能感兴趣的:(ZOJ)