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


                       ZOJ1015

    题意简述:给定一个无向图,判断是否存在一个长度大于3的环路,且其上没有弦(连接环上不同两点的边且不在环上)。

    命题等价于该图是否存在完美消除序列。

    所谓完美消除序列:在 vi,vi+1,...vn vi与之后与vi相邻的点构成一个团(完全子图)。

    求完美消除序列的MCS算法。倒序给点标号,标号为i的点出现在序列的第i项。对每个顶点i,维护标号label[i],表示标号的度,每次选择标号最大的点标号。用堆加速。

    求出了完美消除序列后,只要判断这个序列是否合法就可以得出结论。

    在 vi,vi+1,...vn的导出子图中找到与vi相邻的标号最小(度最小)的点,设为vj,再检查vj是否与每个vi的邻接点相邻。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<algorithm>
    #include<set>
    #define clr(x,y) memset(x,y,sizeof(x))
    using namespace std;
    const int maxn=1010;
    
    vector<int> construct(int n,vector<int> adj[maxn])
    {
     static int rank[maxn],label[maxn];
     clr(rank,-1);clr(label,0);
     priority_queue<pair<int,int> > heap;
     
     for(int i=1;i<=n;i++)
     	heap.push(make_pair(0,i));
    	 
     for(int i=n-1;i>=0;i--)
     	{
     	 while(true)
     	 	{
     	 	 int u=heap.top().second;heap.pop();
     	 	 if(rank[u]==-1)
     	 	 	{
     	 	 	 rank[u]=i;
     	 	 	 for(vector<int>:: iterator iter=adj[u].begin();iter!=adj[u].end();++iter)
     	 	 	 	{
     	 	 	 	 if(rank[*iter]==-1)
     	 	 	 	 	{
     	 	 	 	 	 label[*iter]++;
     	 	 	 	 	 heap.push(make_pair(label[*iter],*iter));
    					}
    				}
    			 break;
    			}
    		}
    	}
     vector<int> result(n);
     for(int i=1;i<=n;i++)	
     	{
     	 result[rank[i]]=i;
    	} 	
     return result;
    }
    
    bool check(int n,vector<int>adj[maxn],vector<int> ord)
    {
     static bool mark[maxn];
     static int rank[maxn];
     for(int i=0;i<n;i++)rank[ord[i]]=i;
     clr(mark,0);
     for(int i=0;i<n;i++)
        {
         vector<pair<int,int> >tmp;
         for(vector<int>::iterator iter=adj[ord[i]].begin();iter!=adj[ord[i]].end();++iter)
         	 if(!mark[*iter])tmp.push_back(make_pair(rank[*iter],*iter));
    	
     sort(tmp.begin(),tmp.end());
     if(tmp.size())
     	{
     	 int u=tmp[0].second;set<int> tmpAdj;
     	 for(vector<int>::iterator iter=adj[u].begin();iter!=adj[u].end();++iter)
     	 	{
     	 	 tmpAdj.insert(*iter);
    		}
    	 for(int i=1;i<(int)tmp.size();++i)
    	 	{
    	 	 if(!tmpAdj.count(tmp[i].second))return false;
    		}
    	}
     mark[ord[i]]=true;
    }
    return true;
    }
    
    bool is_chordal(int nodeCount,vector<pair<int,int> >edges)
    {
     int n=nodeCount;
     vector<int>adj[maxn];
     for(int i=0;i<=n;i++)
     	adj[i].clear();
     for(vector<pair<int,int> >::iterator iter=edges.begin();iter!=edges.end();++iter)
     	{
     	 adj[iter->first].push_back(iter->second);
     	 adj[iter->second].push_back(iter->first);
    	}	
     return check(n,adj,construct(n,adj));
    }
    
    int main()
    {
     int n,m;
     while(scanf("%d%d",&n,&m))
     	{
     	 if(n==0&&m==0)return 0;
     	 vector<pair<int,int> >ed;
     	 for(int i=0;i<m;i++)
     	 	{
     	 	 int a,b;
     	 	 scanf("%d%d",&a,&b);
     	 	 ed.push_back(make_pair(a,b));
    		}
    	 if(is_chordal(n,ed))printf("Perfect
    
    ");
    	 	else printf("Imperfect
    
    ");
    	}
     return 0;
    }
    

      完美消除序列还有广泛的应用,以后来补充。

  • 相关阅读:
    位运算简介以及常用技巧
    JMeter 十六:加密处理
    JMeter 十五:函数以及变量
    JMeter 十四:最佳实践
    JMeter 十三:生成 report dashboard
    JMeter 十二:命令行执行
    JMeter 十一:参数化
    JMeter 十:录制脚本--使用bodboy
    LoadRunner录制:检查点
    LoadRunner录制: 选择协议
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6444707.html
Copyright © 2020-2023  润新知