弦图判定及最小染色数 弦图:所有长度大于3的环均有弦的图叫弦

【转】弦图判定及最小染色数

弦图:所有长度大于3的环均有弦的图叫弦图。
完美消除序列:一个序列{v1,v2,…,vn},满足{vi+1,vi+2,…,vn}中与vi相邻的点的诱导子图为完全图。

弦图的判定(ZOJ 1015)可以采用MCS算法:
基于 定理:一个图无向图是弦图当且仅当它有完美消除序列。
首先找出消除序列:
0.i=n
1.找到一个u∈{j|label[j]=max{label[k]}(k为未标号点)},order[u]=i
2.--i,所有与u相邻的v且++label[v],回到1
也就是说,每次找现有未标号的点中,与已标号的点相邻最多的那个,标号。
然后判断该序列是否是完美消除序列:
对于每一个vi,找到{vi+1,vi+2,…,vn}中与vi相邻的标号最小的点vj,判断其它{vi+1,vi+2,…,vn}中与vi相邻的点是否与vj相邻,若不相邻则不是完美消除序列。

最小染色数(HNOI2008 神奇的国度)可以这样做:
在完美消除序列基础上,从最大标号开始,贪心地染色,最后用了几种颜色即为答案。

只是我想不通为什么CDQ那份PPT里说MCS和染色的复杂度是O(n+m),我只会写O(n^2+m)的…

zoj1015,joj1036 弦图的判定  

2012-04-11 11:21:08|  分类: 数据结构——图论|字号 订阅

弦图:所有长度大于3的环均有弦的图叫弦图。
完美消除序列:一个序列{v1,v2,…,vn},满足{vi+1,vi+2,…,vn}中与vi相邻的点的诱导子图为完全图。

弦图的判定(ZOJ 1015)可以采用MCS算法
基于定理:一个图无向图是弦图当且仅当它有完美消除序列。

首先找出消除序列:
0.i=n
1.找到一个u∈{j|label[j]=max{label[k]}(k为未标号点)},order[u]=i
2.--i,所有与u相邻的v且++label[v],回到1
也就是说,每次找现有未标号的点中,与已标号的点相邻最多的那个,标号。
然后判断该序列是否是完美消除序列:
对于每一个vi,找到{vi+1,vi+2,…,vn}中与vi相邻的标号最小的点vj,判断其它{vi+1,vi+2,…,vn}中与vi相邻的点是否与vj相邻,若不相邻则不是完美消除序列。

实例:无向图G=(V, E),V为图的所有顶点集合(非空),E为图的所有边的集合。

  【子图(subgraph)和生成子图(spanning subgraph)】

  G'=(V', E'),V'被包含于V,E'被包含于E,G'为G的子图。

        另外对于子图有一个生成子图的概念,而者的区别在于:在子图中,E'<=E且V'<=V;在生成子图中,E'<=E,且V'=V。

 

  【诱导子图(induced subgraph)】

  G'=(V', E'),V'被包含于V,E'={(u, v)|u, v属于V',(u, v)属于E},G'为G的诱导子图。

        注意:对于V',只要在G中有边,那么在G'中同样应该有边。

 

  【团(clique)】

  G'为关于V'的完全图。

  一个团为极大团(maximal clique)当且仅当它不是其它团的子图。

  一个图为最大团(maximum clique)当且仅当它的点集模最大。

  一个图的团数表示为ω(G)。

 

  【最小染色(minimum coloring)】

  用最小的颜色给点染色使相邻点颜色不同。此时的颜色数称色数。

  一个图的色数表示为χ(G)。

 

  【最大独立集(maximum independent set)】

  最大的一个点子集使任何两个点不相邻。记为α(G)。

 

  【最小团覆盖(minimum clique cover)】

  用最少个数的团覆盖所有的点。记为κ(G)。

 

  【弦(chord)】

  连接环中不相邻的两个点的边。

 

  【弦图(chordal graph)】

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

 

  【单纯点(simplicial vertex)】

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

  [定理]

  任何一个弦图都至少有一个单纯点,不是完全图的弦图至少有两个不相邻的单纯点。

 

  【完美消除序列(perfect elimination ordering)】

  一个点的序列(每个点出现且恰好出现一次)v[1], v[2], ..., v[n]满足v[i]在{v[i], v[i+1], ..., v[n]}的诱导子图中为一个单纯点。

 

弦图判断

分类: 图论   349人阅读  评论(0)  收藏  举报
定义: 
无向图中,如果任意边数大于3的环,至少存在一条边连接环中不相邻的某两 
个点,则称此图为弦图(Chordal Graph)。 

zoj1015的题目: 
判断无向图是否为弦图,是则输出Perfect,否则输出Imperfect。 

以下是时间复杂度为O(n+m)的算法,n是图的点数,m是图的边数。 
第一步:给节点编号 
设已编号的节点集合为A,未编号的节点集合为B 
开始时A为空,B包含所有节点。 
for num=n-1 downto 0 do 

在B中找节点x,使与x相邻的在A集合中的节点数最多,将x编号为num, 
并从B移入A 

第二步:检查 
for num=0 to n-1 do 

对编号为num的节点x,设所有编号大于num且与x相邻的节点集合为C, 
在集合C中找出编号最小的节点y,如果集合C中存在不等于y的节点z, 
且y与z间没有边,则此图不是弦图,退出。 

检查完了,则此图是弦图。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中判断有向是否为有向无环(DAG)的方法通常使用拓扑排序(topological sort)算法。 拓扑排序算法的基本思路是,从DAG中选择一个没有前驱(即入度为0)的顶点,并输出它,然后把它从中删除,同时更新剩余顶点的入度。重复这个过程直到所有顶点都被输出。如果最后输出的顶点目少于中的顶点目,则该有向中存在环路,因为环路中的顶点之间互相有依赖关系,因此它们的入度都不为0,无法被输出。 下面是一个示例代码,可以判断给定的有向是否为DAG: ```c++ #include <bits/stdc++.h> using namespace std; const int N = 100005; vector<int> G[N]; // 存储的邻接表 int in_degree[N]; // 存储每个点的入度 bool topological_sort(int n) { queue<int> q; for (int i = 1; i <= n; i++) { if (in_degree[i] == 0) q.push(i); // 将所有入度为0的点加入队列 } int cnt = 0; // 计已经输出的顶点目 while (!q.empty()) { int u = q.front(); q.pop(); cnt++; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; in_degree[v]--; if (in_degree[v] == 0) q.push(v); } } return cnt == n; // 如果所有顶点都被输出,则是DAG } int main() { int n, m; cin >> n >> m; // 读入点和边 for (int i = 1; i <= m; i++) { int u, v; cin >> u >> v; // 读入一条边 G[u].push_back(v); // 将边加入邻接表 in_degree[v]++; // 更新入度 } if (topological_sort(n)) { cout << "It is a DAG." << endl; } else { cout << "It is not a DAG." << endl; } return 0; } ``` 在上述代码中,我们使用邻接表存储,使用组`in_degree`存储每个点的入度。在`topological_sort`函中,我们首先将所有入度为0的顶点加入队列,然后不断从队列中取出顶点,并将其所有出边指向的顶点的入度减1。如果某个顶点的入度变为0,就将其加入队列。最终,如果所有顶点都被输出,就说明是DAG,否则说明中存在环路。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值