bzoj 1006 弦图染色
给定一个弦图,问最少染色数。
对于弦图的一个完美消去序列,从后往前染色,每次染可以染的最小编号的颜色,由完美消去序列的定义,序列任一后缀的点的导出子图中,由该后缀第一个元素及其邻接点导出的子图一定是完全图,所以,序列中某一元素染的颜色编号是该完全图的大小。所以最小染色数小于等于最大团的点数,而显然前者又大于等于后者,故弦图的最小染色数等于最大团的大小。
1 /************************************************************** 2 Problem: 1006 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:1672 ms 7 Memory:11968 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <vector> 12 #define maxn 10010 13 using namespace std; 14 15 int n, m; 16 vector<int> g[maxn]; 17 bool done[maxn]; 18 int label[maxn], pos[maxn]; 19 20 int msc() { 21 int rt = 0; 22 for( int i=n; i>=1; i-- ) { 23 int mu = 0; 24 for( int u=1; u<=n; u++ ) { 25 if( !done[u] ) { 26 if( !mu || label[u]>label[mu] ) 27 mu = u; 28 } 29 } 30 done[mu] = true; 31 pos[mu] = i; 32 int cnt = 0; 33 for( int t=0; t<g[mu].size(); t++ ) { 34 int v = g[mu][t]; 35 if( done[v] ) { 36 cnt++; 37 } else { 38 label[v]++; 39 } 40 } 41 rt = max( rt, cnt+1 ); 42 } 43 return rt; 44 } 45 int main() { 46 scanf( "%d%d", &n, &m ); 47 for( int i=1,u,v; i<=m; i++ ) { 48 scanf( "%d%d", &u, &v ); 49 g[u].push_back(v); 50 g[v].push_back(u); 51 } 52 printf( "%d\n", msc() ); 53 }