UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)
题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议。参会骑士至少有3个且有奇数个。
题目分析:在可以相邻的骑士之间连一条无向边,构成一张图G。则问题变成了有几个节点不在奇圈(有奇数个节点的圈)内,并且一个点在圈内最多出现一次。如果G不连通,应该对每一个分量分别求解。奇圈上的点一定在同一个双连通分量内,要找出所有的双连通分量。但是能构成二分图的双连通分量中一定没有奇圈,不能构成二分图的双连通分量中一定含有奇圈,并且分量中所有的点都在奇圈上,所有还要判断每一个双连通分量能不能构成二分图。
其实就是一道模板题。。。
代码如下:
# include<iostream>
# include<cstdio>
# include<vector>
# include<stack>
# include<cstring>
# include<algorithm>
using namespace std; const int maxn=1005;
struct Edge
{
int u,v;
Edge(int _u,int _v):u(_u),v(_v){}
};
stack<Edge>S;
vector<int>G[maxn],bcc[maxn];
int bcc_cnt,dfs_cnt,low[maxn],pre[maxn],odd[maxn],color[maxn],bccno[maxn],iscut[maxn],A[maxn][maxn]; int dfs(int u,int fa)
{
int lowu=pre[u]=++dfs_cnt;
int child=0;
for(int i=0;i<G[u].size();++i){
int v=G[u][i];
if(!pre[v]){
S.push(Edge(u,v));
++child;
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
if(lowv>=pre[u]){///存在一个满足条件的v,便能说明u是割点。
iscut[u]=1;
bcc[++bcc_cnt].clear();
while(1)
{
Edge x=S.top();
S.pop();
if(bccno[x.u]!=bcc_cnt){
bcc[bcc_cnt].push_back(x.u);
bccno[x.u]=bcc_cnt;
}
if(bccno[x.v]!=bcc_cnt){
bcc[bcc_cnt].push_back(x.v);
bccno[x.v]=bcc_cnt;
}
if(x.u==u&&x.v==v)
break;
}
}
}
else if(pre[v]<pre[u]&&v!=fa){
S.push(Edge(u,v));
lowu=min(lowu,pre[v]);
}
}
if(fa<0&&child==1)///根节点只有1个子节点时不是割点。
iscut[u]=0;
low[u]=lowu;
return lowu;
} void find_bcc(int n)
{
memset(pre,0,sizeof(pre));
memset(iscut,0,sizeof(iscut));
memset(bccno,0,sizeof(bccno));
dfs_cnt=bcc_cnt=0;
for(int i=0;i<n;++i)
if(!pre[i])
dfs(i,-1);
} bool bipartite(int u,int b)
{
for(int i=0;i<G[u].size();++i){
int v=G[u][i];
if(bccno[v]!=b)
continue;
if(color[v]==color[u])
return false;
if(!color[v]){
color[v]=3-color[u];
if(!bipartite(v,b))
return false;
}
}
return true;
} int main()
{
int n,m,a,b;
while(scanf("%d%d",&n,&m)&&(n+m))
{
memset(A,0,sizeof(A));
for(int i=0;i<n;++i) G[i].clear();
while(m--){
scanf("%d%d",&a,&b);
--a,--b;
A[a][b]=A[b][a]=1;
}
for(int i=0;i<n;++i)
for(int j=i+1;j<n;++j)
if(!A[i][j])
G[i].push_back(j),G[j].push_back(i); find_bcc(n); memset(odd,0,sizeof(odd));
for(int i=1;i<=bcc_cnt;++i){
memset(color,0,sizeof(color));
for(int j=0;j<bcc[i].size();++j)
bccno[bcc[i][j]]=i;
int u=bcc[i][0];
color[u]=1;
if(!bipartite(u,i))
for(int j=0;j<bcc[i].size();++j)
odd[bcc[i][j]]=1;
}
int ans=n;
for(int i=0;i<n;++i)
if(odd[i])
--ans;
printf("%d\n",ans);
}
return 0;
}
UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)的更多相关文章
- UVALive - 3523 - Knights of the Round Table
Problem UVALive - 3523 - Knights of the Round Table Time Limit: 4500 mSec Problem Description Input ...
- UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
由于互相憎恨的骑士不能相邻,把可以相邻的骑士连上无向边,会议要求是奇数,问题就是求不在任意一个简单奇圈上的结点个数. 如果不是二分图,一定存在一个奇圈,同一个双连通分量中其它点一定可以加入奇圈.很明显 ...
- uvalive 3523 Knights of the Round Table 圆桌骑士(强连通+二分图)
题目真心分析不出来.看了白书才明白,不过有点绕脑. 容易想到,把题目给的不相邻的关系,利用矩阵,反过来建图.既然是全部可行的关系,那么就应该能画出含奇数个点的环.求环即是求双连通分量:找出所有的双连通 ...
- UVALive 3523 : Knights of the Round Table (二分图+BCC)
题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; ; int n,m; int dfn[maxn],low[ ...
- [POJ2942]:Knights of the Round Table(塔尖+二分图染色法)
题目传送门 题目描述 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: .相互憎恨的两个骑士不能坐在直接相邻的 ...
- uva 3523 Knights of the Round Table
题意:给你n,m n为有多少人,m为有多少组关系,每组关系代表两人相互憎恨,问有多少个骑士不能参加任何一个会议. 白书算法指南 对于每个双联通分量,若不是二分图,就把里面的节点标记 #include ...
- Spoj 2878 KNIGHTS - Knights of the Round Table | 双联通分量 二分图判定
题目链接 考虑建立原图的补图,即如果两个骑士不互相憎恨,就在他们之间连一条无向边. 显而易见的是,如果若干个骑士在同一个点数为奇数的环上时,他们就可以在一起开会.换句话说,如果一个骑士被一个奇环包含, ...
- 【LA3523】 Knights of the Round Table (点双连通分量+染色问题?)
Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 12439 Acce ...
随机推荐
- [Windows Powershell]-学习笔记(4)
Powershell 定义变量 在powershell中变量名均是以美元符"$"开始,剩余字符可以是数字.字母.下划线的任意字符,并且powershell变量名大小写不敏感($a和 ...
- ACM-ICPC 2018 南京赛区网络预赛 G. Lpl and Energy-saving Lamps (弱线段树)
线段树节点维护区间最小值,查找时优先从左侧的区间寻找. 每一次循环都在树中不停寻找第一个小于等于当前持有数的值,然后抹去,直到找不到为止. #include<cstdio> #includ ...
- spark 作业提交
kafka-topics.sh --describe --zookeeper xxxxx:2181 --topic testkafka-run-class.sh kafka.tools.GetOffs ...
- zookeeper 监听事件 CuratorWatcher
zookeeper 监听事件 CuratorWatcher CuratorWatcher一次注册只监听一次,不监听查询. 1.监听测试类 package com.qy.learn.zk.curator ...
- PreparedStatement和Statement区别详解
技术原理 该 PreparedStatement接口继承Statement,并与之在两方面有所不同: PreparedStatement 实例包含已编译的 SQL 语句.这就是使语句“准备好”.包含于 ...
- webservice使用方法
1,右击项目选择-->添加服务引用: 填写一个 命名空间名称; 2, 实例化 命名空间名称 ; 选择 带client的服务名称进行初始化 3,开始调用方法 // 带参数的webservice ...
- Python3.x:selenium获取iframe内嵌页面的源码
Python3.x:selenium获取iframe内嵌页面的源码 前言 在一些网页中经常会看到ifrmae/frame标签,iframe是嵌入式框架一般用来在已有的页面中嵌入另一个页面,当一个元素在 ...
- centos安装oracle客户端
使用centos远程登陆oracle服务器: 下载需要的rpm包: [root@node1 oracle]# lltotal 59872-rw-r--r-- 1 root root 59865008 ...
- 20145216史婧瑶《Java程序设计》第5周学习总结
20145216 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 异常处理 8.1 语法与继承架构 Java中所有错误都会被打包为对象,运用try.catch,可以在错误发生 ...
- 20145333 《Java程序设计》第5周学习总结
20145333 <Java程序设计>第5周学习总结 教材学习内容总结 语法与继承架构 使用try.catch Java中所有错误都会被包装成对象,可以尝试(try)执行程序并捕捉(cat ...