一些定义:

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

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

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

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

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

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

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

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

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

BZOJ:

 /**************************************************************
Problem: 1242
User: idy002
Language: C++
Result: Accepted
Time:544 ms
Memory:1816 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#define N 1010
#define M N*N*2 int n, m;
bool c[N][N];
int qu[N], inq[N], dgr[N];
int stk[N], top; void msc() {
dgr[] = -;
for( int i=n; i>=; i-- ) {
int s = ;
for( int u=; u<=n; u++ )
if( !inq[u] && dgr[u]>dgr[s] ) s=u;
qu[i] = s;
inq[s] = true;
for( int u=; u<=n; u++ )
if( !inq[u] && c[s][u] ) dgr[u]++;
}
}
bool check() {
for( int i=n; i>=; i-- ) {
int s=qu[i];
top = ;
for( int j=i+; j<=n; j++ )
if( c[s][qu[j]] ) stk[++top] = qu[j];
if( top== ) continue;
for( int j=; j<=top; j++ )
if( !c[stk[]][stk[j]] ) return false;
}
return true;
}
int main() {
scanf( "%d%d", &n, &m );
for( int i=,u,v; i<=m; i++ ) {
scanf( "%d%d", &u, &v );
c[u][v] = c[v][u] = ;
}
msc();
printf( "%s\n", check() ? "Perfect" : "Imperfect" );
}

ZOJ:

 #include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#define maxn 1010
using namespace std; int n, m;
vector<int> g[maxn];
bool connect[maxn][maxn]; int id[maxn];
int label[maxn];
int seq[maxn]; struct Stat {
int lab, u;
Stat( int lab, int u ) : lab(lab), u(u) {}
bool operator<( const Stat & b ) const {
return lab<b.lab;
}
};
void mcs() {
priority_queue<Stat> pq;
memset( label, , sizeof(label) );
memset( id, , sizeof(id) );
for( int u=; u<=n; u++ ) pq.push(Stat(,u)); for( int i=n; i>=; i-- ) {
while( id[pq.top().u] ) pq.pop();
int u = pq.top().u;
pq.pop();
id[u] = i;
for( int t=; t<g[u].size(); t++ ) {
int v = g[u][t];
if( !id[v] ) {
label[v]++;
pq.push( Stat(label[v],v) );
}
}
}
for( int u=; u<=n; u++ )
seq[id[u]] = u;
} bool check() {
vector<int> c;
for( int i=; i<=n; i++ ) {
int u = seq[i];
c.clear();
for( int t=; t<g[u].size(); t++ ) {
int v = g[u][t];
if( id[v]>id[u] )
c.push_back(v);
}
if( c.empty() ) continue;
int sc = c[];
for( int t=; t<c.size(); t++ )
if( id[c[t]]<id[sc] ) sc=c[t];
for( int t=; t<c.size(); t++ ) {
int v = c[t];
if( v==sc ) continue;
if( !connect[sc][v] ) return false;
}
}
return true;
}
void init( int n ) {
memset( connect, false, sizeof(connect) );
for( int u=; u<=n; u++ ) g[u].clear();
}
int main() {
while() {
scanf( "%d%d", &n, &m );
if( n== && m== ) return ;
init(n);
for( int i=,u,v; i<=m; i++ ) {
scanf( "%d%d", &u, &v );
connect[u][v] = connect[v][u] = true;
g[u].push_back(v);
g[v].push_back(u);
}
mcs();
printf( "%s\n\n", check() ? "Perfect" : "Imperfect" );
}
}

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

O(n^4*...)

 #include <cstdio>
#include <vector>
#include <set>
#define N 110
#define foreach(it,s) for( typeof(s.begin()) it=s.begin(); it!=s.end(); it++ )
using namespace std; int n, m;
set<int> s;
set<int> g[N]; bool find_erase() {
foreach( u, s ) {
vector<int> vc;
foreach( v, g[*u] )
vc.push_back(*v);
bool ok = true;
for( int a=; a<vc.size() && ok; a++ )
for( int b=a+; b<vc.size() && ok; b++ )
if( g[vc[a]].count(vc[b])== )
ok = false;
if( ok ) {
s.erase(*u);
for( int t=; t<g[*u].size(); t++ )
g[vc[t]].erase(*u);
return true;
}
}
return false;
}
int main() {
scanf( "%d%d", &n, &m );
for( int i=; i<=n; i++ )
s.insert(i);
for( int i=,u,v; i<=m; i++ ) {
scanf( "%d%d", &u, &v );
if( g[u].count(v) ) continue;
g[u].insert(v);
g[v].insert(u);
}
for( int t=; t<=n; t++ ) {
if( !find_erase() ) {
printf( "Imperfect\n" );
return ;
}
}
printf( "Perfect\n" );
}

ZOJ 1015 弦图判定的更多相关文章

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

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

  2. [bzoj1242] Zju1015 Fishing Net弦图判定

    弦图判定..MCS算法. 先选一个点,然后每次拿 相邻已选点最多 的未选点. 选完之后判断一下是否是完美消除序列. #include<cstdio> #include<iostrea ...

  3. ZOJ 1015 Fishing Net(弦图判定)

    In a highly modernized fishing village, inhabitants there make a living on fishery. Their major tool ...

  4. bzoj 1242 弦图判定 MCS

    题目大意: 给定一张无向图,判断是不是弦图. 题解: 今天刚学了<弦图与区间图> 本来写了一个60行+的学习笔记 结果因为忘了保存重启电脑后被还原了... 那就算了吧. MCS最大势算法, ...

  5. bzoj1242(弦图判定)

    cdqppt地址:https://wenku.baidu.com/view/a2bf4ad9ad51f01dc281f1df.html: 代码实现参考的http://blog.csdn.net/u01 ...

  6. ●BZOJ 1006 [HNOI2008]神奇的国度(弦图最小染色数)○ZOJ 1015 Fishing Net

    ●赘述题目 给出一张弦图,求其最小染色数. ●题解 网上的唯一“文献”:<弦图与区间图>(cdq),可以学习学习.(有的看不懂) 摘录几个解决改题所需的知识点: ●子图和诱导子图(一定要弄 ...

  7. ZOJ 1015 Fishing Net(判断弦图)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=15 题意:给定一个图.判断是不是弦图? 思路:(1)神马是弦图?对于一 ...

  8. 弦图的判定MCS算法(zoj1015)

    题意:裸的弦图的判定: 弦图定义:给出一个无向连通图,如果每个环中都存在至少一条弦(环中存在不相邻的两点直接相连)这样的图叫做弦图: 转载:http://blog.csdn.net/crux_d/ar ...

  9. BZOJ 1006 完美消除序列&最大势算法&弦图

    K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.所谓N边关系 ...

随机推荐

  1. python操作YAML文件之pyyaml库

    1. YAML简介 YAML是一种被认为可以超越XML.JSON的配置文件,最早接触是Spring Boot,木有想到python也是支持的,遂研究一下. python解析YAML库叫做pyyaml, ...

  2. Oracle笔记之约束

    约束用于保证数据库中某些数据的完整性,给某一列添加一个约束可以保证不满足约束的数据是绝对不会被接受的. 约束主要有那么五种类型:非空约束.唯一约束.主键约束.外键约束.校验约束. 使用如下命令检索某个 ...

  3. Go语言 2 变量、常量和数据类型

    文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ Go学习群:415660935 2.1 变量 变量是对一块内存空间的命名,程序可以通 ...

  4. Java简单爬虫(一)

    简单的说,爬虫的意思就是根据url访问请求,然后对返回的数据进行提取,获取对自己有用的信息.然后我们可以将这些有用的信息保存到数据库或者保存到文件中.如果我们手工一个一个访问提取非常慢,所以我们需要编 ...

  5. Java源码-HashMap(jdk1.8)

    一.hash方法 如下是jdk1.8中的源码 static final int hash(Object key) { int h; return (key == null) ? 0 : (h = ke ...

  6. 使用keytool生成ssl密钥文件keystore和truststore

    最近在研究Mina的开发,通信的时候需要数据加密,而且mina本身支持SSLFilter过滤器,所以可以采用SSL加密的方式对数据进行加密. 在进行加密之前,我们需要使用keytool(这个存在于C: ...

  7. linux 定时执行任务 at atq atrm命令的使用

    1.at命令在指定时刻执行指定的命令序列 at [-V] [-q 队列] [-f 文档名] [-mldbv] 时间 下面对命令中的参数进行说明.-V 将标准版本号打印到标准错误中.-q queue 使 ...

  8. HDU 1024 Max Sum Plus Plus(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024 题目大意:有多组输入,每组一行整数,开头两个数字m,n,接着有n个数字.要求在这n个数字上,m块 ...

  9. 三年.NET即将转Java,我该何去何从

    2014年5月,大三报了某培训班5个月学习.NET 2014年12月-2015年6月,在某软件公司实习,用ASP.NET开发企业级系统 2015年7月-2017年3月,从毕业生到成为该公司的主要开发人 ...

  10. Redis实战(七)

    修改数据 C#语言修改Redis示例. 1.通过key修改单个value using (var redisClient = RedisManager.GetClient()) { var user = ...