一些定义:
弦图是一种特殊图:它的所有极小环都只有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 }
时间: 2024-10-05 23:25:06