一些定义:
弦图是一种特殊图:它的所有极小环都只有3个顶点。
单纯点:该顶点与其邻接点在原图中的导出子图是一个完全图。
图G的完美消去序列:一个顶点序列a1a2a3...an,使得对于每个元素ai,ai在ai、ai+1、ai+2...an的导出子图中是一个单纯点。
弦图有一个性质:任何一个弦图都至少存在一个单纯点(该点和其邻接点组成一个完全图)
弦图另一个性质:一个图是弦图当且仅当其存在完美消去序列。(归纳证明)
最大势算法(msc):若原图是弦图,则该算法计算出的序列是完美消去序列。
算法大致思想:从后往前计算序列,每次选择点v作为序列中的元素,v是还未选的点中与已经选了的点连边最多的点。
然后检查该序列是否是完美消去序列。
请看陈丹琦的ppt:《弦图与区间图》
BZOJ:
1 /************************************************************** 2 Problem: 1242 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:544 ms 7 Memory:1816 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #define N 1010 13 #define M N*N*2 14 15 int n, m; 16 bool c[N][N]; 17 int qu[N], inq[N], dgr[N]; 18 int stk[N], top; 19 20 void msc() { 21 dgr[0] = -1; 22 for( int i=n; i>=1; i-- ) { 23 int s = 0; 24 for( int u=1; u<=n; u++ ) 25 if( !inq[u] && dgr[u]>dgr[s] ) s=u; 26 qu[i] = s; 27 inq[s] = true; 28 for( int u=1; u<=n; u++ ) 29 if( !inq[u] && c[s][u] ) dgr[u]++; 30 } 31 } 32 bool check() { 33 for( int i=n; i>=1; i-- ) { 34 int s=qu[i]; 35 top = 0; 36 for( int j=i+1; j<=n; j++ ) 37 if( c[s][qu[j]] ) stk[++top] = qu[j]; 38 if( top==0 ) continue; 39 for( int j=2; j<=top; j++ ) 40 if( !c[stk[1]][stk[j]] ) return false; 41 } 42 return true; 43 } 44 int main() { 45 scanf( "%d%d", &n, &m ); 46 for( int i=1,u,v; i<=m; i++ ) { 47 scanf( "%d%d", &u, &v ); 48 c[u][v] = c[v][u] = 1; 49 } 50 msc(); 51 printf( "%s\n", check() ? "Perfect" : "Imperfect" ); 52 } 53