码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 1015 弦图判定

时间:2015-02-17 19:54:15      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:

 

一些定义:

弦图是一种特殊图:它的所有极小环都只有3个顶点。

单纯点:该顶点与其邻接点在原图中的导出子图是一个完全图。

图G的完美消去序列:一个顶点序列a1a2a3...an,使得对于每个元素ai,ai在ai、ai+1、ai+2...an的导出子图中是一个单纯点。

 

弦图有一个性质:任何一个弦图都至少存在一个单纯点(该点和其邻接点组成一个完全图)

弦图另一个性质:一个图是弦图当且仅当其存在完美消去序列。(归纳证明)

 

最大势算法(msc):若原图是弦图,则该算法计算出的序列是完美消去序列。

算法大致思想:从后往前计算序列,每次选择点v作为序列中的元素,v是还未选的点中与已经选了的点连边最多的点。

然后检查该序列是否是完美消去序列。

 

请看陈丹琦的ppt:《弦图与区间图》

 

技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #include <vector>
 5 #define maxn 1010
 6 using namespace std;
 7 
 8 int n, m;
 9 vector<int> g[maxn];
10 bool connect[maxn][maxn];
11 
12 int id[maxn];
13 int label[maxn];
14 int seq[maxn];
15 
16 struct Stat {
17     int lab, u;
18     Stat( int lab, int u ) : lab(lab), u(u) {}
19     bool operator<( const Stat & b ) const { 
20         return lab<b.lab;
21     }
22 };
23 void mcs() {
24     priority_queue<Stat> pq;
25     memset( label, 0, sizeof(label) );
26     memset( id, 0, sizeof(id) );
27     for( int u=1; u<=n; u++ ) pq.push(Stat(0,u));
28 
29     for( int i=n; i>=1; i-- ) {
30         while( id[pq.top().u] ) pq.pop();
31         int u = pq.top().u;
32         pq.pop();
33         id[u] = i;
34         for( int t=0; t<g[u].size(); t++ ) {
35             int v = g[u][t];
36             if( !id[v] ) {
37                 label[v]++;
38                 pq.push( Stat(label[v],v) );
39             }
40         }
41     }
42     for( int u=1; u<=n; u++ ) 
43         seq[id[u]] = u;
44 }
45 
46 bool check() {
47     vector<int> c;
48     for( int i=1; i<=n; i++ ) {
49         int u = seq[i];
50         c.clear();
51         for( int t=0; t<g[u].size(); t++ ) {
52             int v = g[u][t];
53             if( id[v]>id[u] ) 
54                 c.push_back(v);
55         }
56         if( c.empty() ) continue;
57         int sc = c[0];
58         for( int t=1; t<c.size(); t++ ) 
59             if( id[c[t]]<id[sc] ) sc=c[t];
60         for( int t=0; t<c.size(); t++ ) {
61             int v = c[t];
62             if( v==sc ) continue;
63             if( !connect[sc][v] ) return false;
64         }
65     }
66     return true;
67 }
68 void init( int n ) {
69     memset( connect, false, sizeof(connect) );
70     for( int u=1; u<=n; u++ ) g[u].clear();
71 }
72 int main() {
73     while(1) {
74         scanf( "%d%d", &n, &m );
75         if( n==0 && m==0 ) return 0;
76         init(n);
77         for( int i=1,u,v; i<=m; i++ ) {
78             scanf( "%d%d", &u, &v );
79             connect[u][v] = connect[v][u] = true;
80             g[u].push_back(v);
81             g[v].push_back(u);
82         }
83         mcs();
84         printf( "%s\n\n", check() ? "Perfect" : "Imperfect" );
85     }
86 }
View Code

 

ZOJ 1015 弦图判定

标签:

原文地址:http://www.cnblogs.com/idy002/p/4295392.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!