bzoj 1006 神奇的国度
题目大意:给定n个点,m对矛盾关系,求最少可以划分为多少个集合
此题涉及到弦图与完美消除序列的知识, 详见 cdq 论文 《弦图与区间图》
我们可以求出当前图的完美消除序列,再倒着进行染色,每次选择可以染的颜色中编号最小的
1 #define MAXN 10010UL 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 int n, m, t, q[MAXN], cr[MAXN], d[MAXN], deg[MAXN], bg[MAXN]; 8 bool vis[MAXN]; 9 10 struct Edge { 11 int hou, nt; 12 }sg[MAXN*200]; 13 14 void Add(int x, int y) { 15 sg[t] = (Edge){y, d[x]}, d[x] = t ++; 16 sg[t] = (Edge){x, d[y]}, d[y] = t ++; 17 return; 18 } 19 20 int main() { 21 memset(d, -1, sizeof(d)); 22 int x, y; 23 scanf("%d%d", &n, &m); 24 for(int i = 1 ; i <= m ; ++ i) { 25 scanf("%d%d", &x, &y); 26 Add(x, y); 27 } 28 for(int i = n ; i >= 1 ; -- i) { 29 int pos = 0; 30 for(int j = n ; j >= 1 ; -- j) if((!vis[j]&&(pos==0||deg[j]>deg[pos]))) pos = j; 31 q[i] = pos, vis[pos] = true; 32 for(int j = d[pos] ; j != -1 ; j = sg[j].nt) ++ deg[sg[j].hou]; 33 } 34 int ans = 0; 35 for(int i = n ; i >= 1 ; -- i) { 36 for(int j = d[q[i]] ; j != -1 ; j = sg[j].nt) bg[cr[sg[j].hou]] = i; 37 int j = 1; 38 while(bg[j]==i) ++ j; 39 cr[q[i]] = j; 40 if(j>ans) ans = j; 41 } 42 printf("%d", ans); 43 return 0; 44 }