zoukankan      html  css  js  c++  java
  • 弦图的判定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
    
    ");
            }
            else
                printf("Imperfect
    
    ");
        }
        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
    
    ");
            else
                printf("Imperfect
    
    ");
        }
    }
    



  • 相关阅读:
    今天写一篇随想,也当是回顾过去,展望未来吧。
    推荐 Word、EXCEL必备工具箱
    elasticsearch Routing 路由详解
    Python学习之字典
    ES 分片和副本数 调整及数据写入、重建索引调优
    fastJson JSON.parseObject()丢失字符串原本顺序
    Python 列表(详)
    pycharm常用快捷键
    Python学习笔记二(列表)
    python学习笔记二
  • 原文地址:https://www.cnblogs.com/mypsq/p/4348114.html
Copyright © 2011-2022 走看看