陈丹琪《弦图与区间图》总结

弦(chord):连接环中不相邻的两个点的边。

弦图(chordalgraph):一个无向图称为弦图当且仅当图中任意长度大于3的环都至少有一个弦。

单纯点(simplicialvertex):设N(v)表示与点v相邻的点集。一个点称为单纯点当{v} + N(v)的诱导子图为一个团。

完美消除序列(perfect elimination ordering):这是一个序列{v[i]},它满足v[i]在{v[i..n]}的诱导子图中为单纯点。

弦图的判定:存在完美消除序列的图为弦图。可以用MCS最大势算法求出完美消除序列。

最大势算法 Maximum Cardinality Search

从n到1的顺序依次给点标号(标号为i的点出现在完美消除序列的第i个)。

设label[i]表示第i个点与多少个已标号的点相邻,每次选择label[i]最大的未标号的点进行标号。

用n个vector来保存label为i的是哪些点,可以使复杂度达到O(n+m)。

弦图上的问题:

用最少的颜色给每个点染色使得相邻的点染的颜色不同:完美消除序列从后往前依次给每个点染上可以染的最小的颜色。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<algorithm>
 5 #define MAX(a,b) a>b?a:b
 6 #define MIN(a,b) a<b?a:b
 7 #define mem(a) memset(a,0,sizeof(a))
 8 #define rep(i,n) for (i=1;i<=(n);i++)
 9 #define INF 1000000000
10 #define N 11000
11 #define M 2100000
12 using namespace std;
13 int ans,b[N],c[N],lab[N],j,vis[N],a[N],ee,m,nex[M],head[N],e[M],u,v,i,n,best;
14 vector<int> vec[N];
15 void add(int u,int v)
16 {
17     e[++ee]=v;nex[ee]=head[u];head[u]=ee;
18 }
19 int main()
20 {
21     scanf("%d%d",&n,&m);
22     rep(i,m)
23     {
24         scanf("%d%d",&u,&v);
25         add(u,v);
26         add(v,u);
27     }
28     best=0;
29     for (i=1;i<=n;i++)
30         vec[0].push_back(i);
31     for (i=n;i>=1;i--)
32     {
33         while (1)
34         {
35             u=vec[best].back();
36             if (vis[u])
37                 vec[best].pop_back();
38             else
39                 break;
40             while (vec[best].size()==0)
41                 best--;
42         }
43         a[i]=u;
44         vis[u]=1;
45         for (j=head[u];j>0;j=nex[j])
46         {
47             lab[e[j]]++;
48             best=MAX(lab[e[j]],best);
49             vec[lab[e[j]]].push_back(e[j]);
50         }
51     }
52     //for (i=1;i<=n;i++)printf("lbz %d
",a[i]);
53         
54     for (i=n;i>=1;i--)
55     {
56         for (j=head[a[i]];j>0;j=nex[j])
57         {
58             b[c[e[j]]]=i;
59         }    
60         rep(j,n)
61             if (b[j]!=i)
62             {
63                 c[a[i]]=j;
64                 ans=MAX(ans,c[a[i]]);
65                 break;
66             }
67     }
68     printf("%d
",ans);
69     return 0;
70 
71 }
栗题:1006: [HNOI2008]神奇的国度

 最大独立集:完美消除序列从前往后能选就选。

判断一个序列是否为完美消除序列:设{vi+1,…,vn}中所有与vi相邻的点依次为vj1,…, vjk。只需判断vj1是否与vj2,…, vjk相邻即可。

区间图(Interval Graph):给定一些区间,定义一个相交图为每个顶点表示一个区间,两个点有边当且仅当两个区间的交集非空。

区间图一定是弦图。


给定n个区间,所对应的区间图为G
G的一个完美消除序列:将所有的区间按照右端点从小到大排序。

------------------------------------------------------------------------- 花有重开日,人无再少年
原文地址:https://www.cnblogs.com/lbz007oi/p/5993590.html