一些定义:

弦图是一种特殊图:它的所有极小环都只有3个顶点。

单纯点:该顶点与其邻接点在原图中的导出子图是一个完全图。

图G的完美消去序列:一个顶点序列a1a2a3...an,使得对于每个元素ai,ai在ai、ai+1、ai+2...an的导出子图中是一个单纯点。

弦图有一个性质:任何一个弦图都至少存在一个单纯点(该点和其邻接点组成一个完全图)

弦图另一个性质:一个图是弦图当且仅当其存在完美消去序列。(归纳证明)

最大势算法(msc):若原图是弦图,则该算法计算出的序列是完美消去序列。

算法大致思想:从后往前计算序列,每次选择点v作为序列中的元素,v是还未选的点中与已经选了的点连边最多的点。

然后检查该序列是否是完美消去序列。

请看陈丹琦的ppt:《弦图与区间图》

BZOJ:

 1 /**************************************************************
 2     Problem: 1242
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:544 ms
 7     Memory:1816 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11 #include <cstring>
12 #define N 1010
13 #define M N*N*2
14
15 int n, m;
16 bool c[N][N];
17 int qu[N], inq[N], dgr[N];
18 int stk[N], top;
19
20 void msc() {
21     dgr[0] = -1;
22     for( int i=n; i>=1; i-- ) {
23         int s = 0;
24         for( int u=1; u<=n; u++ )
25             if( !inq[u] && dgr[u]>dgr[s] ) s=u;
26         qu[i] = s;
27         inq[s] = true;
28         for( int u=1; u<=n; u++ )
29             if( !inq[u] && c[s][u] ) dgr[u]++;
30     }
31 }
32 bool check() {
33     for( int i=n; i>=1; i-- ) {
34         int s=qu[i];
35         top = 0;
36         for( int j=i+1; j<=n; j++ )
37             if( c[s][qu[j]] ) stk[++top] = qu[j];
38         if( top==0 ) continue;
39         for( int j=2; j<=top; j++ )
40             if( !c[stk[1]][stk[j]] ) return false;
41     }
42     return true;
43 }
44 int main() {
45     scanf( "%d%d", &n, &m );
46     for( int i=1,u,v; i<=m; i++ ) {
47         scanf( "%d%d", &u, &v );
48         c[u][v] = c[v][u] = 1;
49     }
50     msc();
51     printf( "%s\n", check() ? "Perfect" : "Imperfect" );
52 }
53 

View Code

ZOJ:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #include <vector>
 5 #define maxn 1010
 6 using namespace std;
 7
 8 int n, m;
 9 vector<int> g[maxn];
10 bool connect[maxn][maxn];
11
12 int id[maxn];
13 int label[maxn];
14 int seq[maxn];
15
16 struct Stat {
17     int lab, u;
18     Stat( int lab, int u ) : lab(lab), u(u) {}
19     bool operator<( const Stat & b ) const {
20         return lab<b.lab;
21     }
22 };
23 void mcs() {
24     priority_queue<Stat> pq;
25     memset( label, 0, sizeof(label) );
26     memset( id, 0, sizeof(id) );
27     for( int u=1; u<=n; u++ ) pq.push(Stat(0,u));
28
29     for( int i=n; i>=1; i-- ) {
30         while( id[pq.top().u] ) pq.pop();
31         int u = pq.top().u;
32         pq.pop();
33         id[u] = i;
34         for( int t=0; t<g[u].size(); t++ ) {
35             int v = g[u][t];
36             if( !id[v] ) {
37                 label[v]++;
38                 pq.push( Stat(label[v],v) );
39             }
40         }
41     }
42     for( int u=1; u<=n; u++ )
43         seq[id[u]] = u;
44 }
45
46 bool check() {
47     vector<int> c;
48     for( int i=1; i<=n; i++ ) {
49         int u = seq[i];
50         c.clear();
51         for( int t=0; t<g[u].size(); t++ ) {
52             int v = g[u][t];
53             if( id[v]>id[u] )
54                 c.push_back(v);
55         }
56         if( c.empty() ) continue;
57         int sc = c[0];
58         for( int t=1; t<c.size(); t++ )
59             if( id[c[t]]<id[sc] ) sc=c[t];
60         for( int t=0; t<c.size(); t++ ) {
61             int v = c[t];
62             if( v==sc ) continue;
63             if( !connect[sc][v] ) return false;
64         }
65     }
66     return true;
67 }
68 void init( int n ) {
69     memset( connect, false, sizeof(connect) );
70     for( int u=1; u<=n; u++ ) g[u].clear();
71 }
72 int main() {
73     while(1) {
74         scanf( "%d%d", &n, &m );
75         if( n==0 && m==0 ) return 0;
76         init(n);
77         for( int i=1,u,v; i<=m; i++ ) {
78             scanf( "%d%d", &u, &v );
79             connect[u][v] = connect[v][u] = true;
80             g[u].push_back(v);
81             g[v].push_back(u);
82         }
83         mcs();
84         printf( "%s\n\n", check() ? "Perfect" : "Imperfect" );
85     }
86 }

View Code

暴力:每次找单纯点,删掉,再找,如果能删完就说明是.

O(n^4*...)

 1 #include <cstdio>
 2 #include <vector>
 3 #include <set>
 4 #define N 110
 5 #define foreach(it,s) for( typeof(s.begin()) it=s.begin(); it!=s.end(); it++ )
 6 using namespace std;
 7
 8 int n, m;
 9 set<int> s;
10 set<int> g[N];
11
12 bool find_erase() {
13     foreach( u, s ) {
14         vector<int> vc;
15         foreach( v, g[*u] )
16             vc.push_back(*v);
17         bool ok = true;
18         for( int a=0; a<vc.size() && ok; a++ )
19             for( int b=a+1; b<vc.size() && ok; b++ )
20                 if( g[vc[a]].count(vc[b])==0 )
21                     ok = false;
22         if( ok ) {
23             s.erase(*u);
24             for( int t=0; t<g[*u].size(); t++ )
25                 g[vc[t]].erase(*u);
26             return true;
27         }
28     }
29     return false;
30 }
31 int main() {
32     scanf( "%d%d", &n, &m );
33     for( int i=1; i<=n; i++ )
34         s.insert(i);
35     for( int i=1,u,v; i<=m; i++ ) {
36         scanf( "%d%d", &u, &v );
37         if( g[u].count(v) ) continue;
38         g[u].insert(v);
39         g[v].insert(u);
40     }
41     for( int t=1; t<=n; t++ ) {
42         if( !find_erase() ) {
43             printf( "Imperfect\n" );
44             return 0;
45         }
46     }
47     printf( "Perfect\n" );
48 }

View Code

转载于:https://www.cnblogs.com/idy002/p/4295392.html

ZOJ 1015 弦图判定相关推荐

  1. bzoj 1242: Zju1015 Fishing Net 弦图判定

    1242: Zju1015 Fishing Net弦图判定 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 214  Solved: 81 [Subm ...

  2. bzoj 1242 Zju1015 Fishing Net 弦图判定

    1242: Zju1015 Fishing Net弦图判定 Time Limit: 10 Sec  Memory Limit: 162 MB [Submit][Status][Discuss] Des ...

  3. bzoj1242: Zju1015 Fishing Net弦图判定

    Description 在一个高度信息化的渔村,鱼网的制作和修补都是由电脑完成.众所周知,鱼网是由网组成的(废话),网组成的东西叫网眼.如果网眼够小,就能捕到很多鱼:如果网眼太大,鱼就会全部漏走.每次 ...

  4. 图论 —— 弦图 —— LexBFS 算法

    [概述] LexBFS 是字典序广度优先搜索(Lexicographic BFS),其常用于弦图的判定. 每次按从 n 到 1 的顺序依次给点编号,每个点维护一个 list,用于记录与其相邻的已标号点 ...

  5. 弦图与完美消除序列(bzoj 1006: [HNOI2008]神奇的国度)

    诱导子图:子图中任意一条边的两个端点一定也都在这个子图中 最大团:团中任意两点之间一定都有边,而包含顶点最多的团就是最大团 最小团覆盖:用最少的团覆盖图中所有的点 最大独立集:独立集中任意两点之间一定 ...

  6. 图论:关于弦图的几个图论结论

    定义 弦:连接环中不相邻的两个点的边 一个图是弦图当图中任意长度大于3的环都至少有一个弦. α(G):\alpha(G):α(G):图GGG中最大独立集的大小,称为最大独立集数 κ(G):\kappa ...

  7. 概率图模型-可分解图-连接树算法-弦图-图论

    概率图模型–精确推断算法的原理 本文主要内容 本文从可分解图出发,逐渐引入弦图,三角化图,然后揭示了为什么引入可分解图,因为可分解图是在连接树算法中最终得到的,还讲解了为什么要使用连接树算法,因为连接 ...

  8. 图论 —— 弦图 —— MCS 算法

    [概述] MCS 算法是最大势算法(Maximum Cardinality Search),其常用于弦图的判定.求弦图的最大团.最小着色.最大独立集.最小团覆盖等. 一个无向图的弦图当且仅当其有一个完 ...

  9. P3196 [HNOI2008]神奇的国度(弦图的最小染色问题)

    整理的算法模板合集: ACM模板 题目传送门 K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国 ...

最新文章

  1. 百度:请叫我卡车新势力
  2. Androidstudio高效管理第三方API的KEY及Gradle版本管理
  3. AOP - PostSharp 2.0
  4. 解决idea application context not configured for this file的问题
  5. UART_RECV详细设计方案
  6. 全国计算机等级考试题库二级C操作题100套(第61套)
  7. 【ElasticSearch】Es 源码之 MetaStateService 源码解读
  8. npm 报错: npm ERR! code ERESOLVE , npm ERR! code E404
  9. PTA: 6-5 删除单链表偶数节点 (20 分)
  10. html ui 下拉列表,html - 如何给样式Material-ui选择字段下拉菜单?
  11. 蓝鹰立德的SAP解决方案开启飞马模式(FMEA)
  12. 【数据分享】中国城市统计年鉴_2001-2021年
  13. tf.matmul()和tf.multipy()的区别
  14. xml的三种解析方法
  15. pe计算机找桌面文件,如何在Windows pe打开桌面文件夹?找不到原桌面文件夹怎么办?...
  16. 万物互联,该怎么联?
  17. python中repeat_Python中的Repeat类方法
  18. 【gp数据库】查询函数中引用数据表信息
  19. 韩剧机器人题材的_有这九部题材不同风格各异的韩剧,你这个冬天可不会剧荒了...
  20. 从施耐德的M262 谈PLC 处理器的演进

热门文章

  1. Hyper-V虚拟化测试12非计划的故障转移
  2. Windows 8实例教程系列 - 开篇
  3. 笔记下UltraEdit的一些常用使用技巧
  4. 蓝桥杯 ADV-126 算法提高 扫雷
  5. [Java] 蓝桥杯BASIC-23 基础练习 芯片测试
  6. PAT 1088 三人行(20 分)- 乙级
  7. 【iOS10】使用XCode8、Swift3. 操作SQLite3数据库的步骤(包括配置环境和SQLite语句)
  8. oracle Lpad()函数和Rpad()函数的用法
  9. java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/Str
  10. 通过java程序实现mysql 批量一个表的子段更新另一个表的字段