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 }
View Code

 

posted @ 2016-04-28 21:15  assassain  阅读(132)  评论(0编辑  收藏  举报