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 ...
随机推荐
- 实参相依查找[条款25]----《C++必知必会》
名字空间对现代C++编程和设计有着深远的影响.其中有些影响直接而明显,例如using声明和using 指令以及采用名字空间作用域加以限定的名字.然而,名字空间还有一些在语法上不那么明显但任然很有基础. ...
- SQL Server去重和判断是否为数字——OBJECT_ID的使用
sql 语句查询时去掉重复项: 使用 distinct 去掉重复项: 首先可以明确的看到存在重复的名字,那么接下来就让我们试试使用 distinct 去重吧. select distinct * fr ...
- Django 分页查询并返回jsons数据,中文乱码解决方法
Django 分页查询并返回jsons数据,中文乱码解决方法 一.引子 Django 分页查询并返回 json ,需要将返回的 queryset 序列化, demo 如下: # coding=UTF- ...
- weblogic控制台部署web项目图解
图解网址:http://jingyan.baidu.com/article/c74d6000650d470f6b595d72.html
- 基础知识总结之 jdk部分
第一次安装jdk 按照操作走完 会出现 C:\Program Files\Java\jdk1.8.0_91 和 C:\Program Files\Java\jre1.8.0_91 两个目录 (平级目 ...
- 负载均衡技术在CDN中发挥着重要作用
转载地址:http://www.qicaispace.com/gonggao/server/page01/info07.asp CDN是一个经策略性部署的整体系统,能够帮助用户解决分布式存储.负载均衡 ...
- 编写和运行简单的"Hello World"操作系统内核
通常编写一个操作系统内核是一项浩大的工程.但我今天的目标是制作一个简单的内核,用比较方便的方法在虚拟机上验证它能够被grub装载和运行,并且可通过gdb进行调试,为接下去的工作创造一个基础环境. 首先 ...
- python 数据分析----matplotlib
Matplotlib是一个强大的Python绘图和数据可视化的工具包. 安装方法:pip install matplotlib 引用方法:import matplotlib.pyplot as plt ...
- RocEDU.阅读.写作《乌合之众》(一)
序言 作者在序言里主要论述了时代演变的内在原因,表明对群体进行研究的重要性,阐述了研究群体行为特征时的研究方法,并概述了群体的发展过程. 造成文明变革的唯一重要变化,是影响到思想.观念和信仰的变化.目 ...
- 20145322 《Java程序设计》第7周学习总结
20145322何志威 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 如果使用JDK8的话,可以使用Lambda特性去除重复的信息. 在只有Lambda表达式的情况下,参 ...