BZOJ 1006 神奇的国度[弦图 MCS求完美消除序列]
2014-09-17 21:33
369 查看
chordal graph-弦图
1.定义弦图(chordalgraph)是指当无向图中任意长度大于3的环都至少有一个弦。所谓弦(chord)是指连接环中不相邻的两个点的边,如下图所示
大家都知道子图的概念,这里加入一个诱导子图(induced subgraph)的定义:
为了更好的理解弦图的概念,我们引进单纯点(simplicialvertex)的定义:N(v)表示与点v相邻的所有点集。一个点称为单纯点当{v}+N(v)的诱导子图为一个团({v}+N(v)的点集以及由这些点集在原图中的所有边的构成的图是一个团)如下图中的红圈圈住的点为单纯点:
团:给定无向图G=(V,E)。如果U包含于V,且对任意u∈U,v∈U,存在边(u,v)∈E,则称U是G的完全子图。G的完全子图U是G的团当且仅当U不包含在G的更大的完全子图中。G的最大团是指G中所含顶点数最多的团。下图G中,子集{1,2}是G的大小为2的完全子图。这个完全子图不是最大团,因为它被G的更大的完全子图{1,2,5}包含。{1,2,5}是G的最大团。{1,4,5}和{2,3,5}也是G的最大团:
2.判断方法
一个无向图是弦图当且仅当它有一个完美消除序列。而完美消除序列(perfect eliminationordering)是指一个点的序列(每个点出现且恰好出现一次)vi在{vi,vi+1,…,vn}的诱导子图中为一个单纯点。于是有了MCS算法,从n到1的顺序依次给点标号(标号为i的点出现在完美消除序列的第i个),设label[i]表示第i个点与多少个已标号的点相邻,每次选择label[i]最大的未标号的点进行标号,伪代码如下:
MCS(G, order) { for all vertices v in G do Label[v] = 0 for i from n to 1 do { choose an unnumbered vertex v with largest Label order[v] = i for all unnumbered vertices u adjacent to v do Label[u]++ } }
然后判断该序列是否是完美消除序列:对于每一个vi,找到{vi+1,vi+2,…,vn}中与vi相邻的标号最小的点vj,
判断其它{vi+1,vi+2,…,vn}中与vi相邻的点是否与vj相邻,若不相邻则不是完美消除序列。从而可以判断是不是弦图。
3.扩展
弦图的方法有着很多经典用途:例如用最少的颜色给每个点染色使得相邻的点染的颜色不同,通过完美消除序列从后往前依次给每个点染色,给每个点染上可以染的最小的颜色;最大独立集问题,选择最多的点使得任意两个点不相邻,通过完美消除序列从前往后能选就选。
我们再引入区间图的思想,
会惊奇地发现它也是弦图。给定一些区间,定义一个相交图为每个顶点表示一个区间,两个点有边当且仅当两个区间的交集非空,如下图所示的区间图:
很显然区间图一定是弦图。这是因为如果存在一个长度大于3的无弦环,刚Ii与Ii+1相交的部分pi一定严格递增或严格递减,以递增为例,即p1< pn。但由于第一个I1与最后一个In相交刚得出pn <p1产生矛盾。所以区间图一定是弦图。给定n个区间,要求选择最多的区间使得区间不互相重叠,这个问题就是区间图的最大独立集问题。
/************************************************************************* > File Name: 67.cpp > Author: wjzdmr > Mail: wjzdmr@gmail.com > Created Time: 2014年09月17日 星期三 20时03分40秒 ************************************************************************/ #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> #include <cmath> #include <vector> #include <list> #include <deque> #include <queue> #include <cctype> #include <map> #include <set> #include <bitset> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iomanip> #include <cstdlib> #include <ctime> #include <cassert> #include <limits> #include <fstream> using namespace std; #define mem(A, X) memset(A, X, sizeof A) #define pb(x) push_back(x) #define mp(x,y) make_pair((x),(y)) #define vi vector<int> #define all(x) x.begin(), x.end() #define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e) #define sz(x) (int)((x).size()) #define sl(a) strlen(a) #define rep(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i)) #define Rep(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i)) #define min3(a,b,c) min(a,min(b,c)) #define max3(a,b,c) max(a,max(b,c)) #define dbg(a) cout << a << endl; #define fi first #define se second typedef long long int64; int gcd(const int64 &a, const int64 &b) { return b == 0 ? a : gcd(b, a % b); } int64 int64pow(int64 a, int64 b){ if (b == 0) return 1; int64 t = int64pow(a, b / 2); if (b % 2) return t * t * a; return t * t; } const int inf = 1 << 30; const double eps = 1e-8; const double pi = acos(-1.0); const int MAX_N = 10005; int n, m; vi arr[MAX_N]; int R[MAX_N], SA[MAX_N], label[MAX_N]; priority_queue <pair<int, int> > heap; void work() { Rep(i, 1, n) { arr[i].clear(); } int u, v; Rep(i, 1, m) { scanf("%d%d", &u, &v); arr[u].pb(v); arr[v].pb(u); } fill(R + 1, R + n + 1, -1); fill(label + 1, label + n + 1, 0); Rep(i, 1, n) { heap.push(mp(0, i)); } //MCS求弦图的完美消除序列 for (int cnt = n; cnt >= 1; ) { int id = heap.top().se; heap.pop(); if (R[id] != -1) continue; SA[cnt] = id; R[id] = cnt--; rep(i, 0, sz(arr[id])) { int u = arr[id][i]; if (R[u] != -1) continue; label[u]++; heap.push(mp(label[u], u)); } } } void Color(int u) { rep(i, 0, sz(arr[u])) { int v = arr[u][i]; if (label[v] == -1) continue; R[label[v]] = u; } for (int i = 1; label[u] == -1; ++i) { if (R[i] != u) label[u] = i; } } int Color_Graph() { fill(label + 1, label + n + 1, -1); fill(R + 1, R + n + 1, -1); for (int i = n; i > 0; --i) Color(SA[i]); int ans = 0; Rep(i, 1, n) ans = max(ans, label[i]); return ans; } int main() { while (cin >> n >> m) { work(); cout << Color_Graph() << endl; } return 0; }
相关文章推荐
- [弦图 最小染色 完美消除序列 MCS算法] BZOJ 1006 [HNOI2008]神奇的国度
- [BZOJ1006][[HNOI2008]神奇的国度][MCS,完美消除序列]
- bzoj 1006: [HNOI2008]神奇的国度 弦图的染色问题&&弦图的完美消除序列
- 弦图与完美消除序列(bzoj 1006: [HNOI2008]神奇的国度)
- [BZOJ1006]神奇的国度(完美消除序列)
- [完美消除序列]BZOJ1006: [HNOI2008]神奇的国度
- bzoj1006 神奇的国度【完美消除序列】
- bzoj1006 弦图转完美消除序列,最小染色
- BZOJ1006 神奇的国度 【弦图染色——最大势算法MCS】
- BZOJ1006 神奇的国度 【弦图染色——最大势算法MCS】
- [弦图判定 完美消除序列 MCS算法] BZOJ 1242 Zju1015 Fishing Net弦图判定
- BZOJ 1006 神奇的国度 弦图 最大势算法
- 【MCS】bzoj1006: [HNOI2008]神奇的国度
- 【BZOJ1006】神奇的国度(弦图)
- [bzoj1006](HNOI2008)神奇的国度(弦图最小染色)【太难不会】
- BZOJ 1006: [HNOI2008]神奇的国度 &&弦图学习笔记
- bzoj 1006: [HNOI2008]神奇的国度(弦图 MCS算法)
- 【BZOJ1006】神奇的国度(弦图)
- 【BZOJ1006】【HNOI2008】神奇的国度(弦图染色)
- [bzoj1006][HNOI2008]神奇的国度【弦图】