题目大意:有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 (双连通分量+二分图匹配)的更多相关文章

  1. UVALive - 3523 - Knights of the Round Table

    Problem  UVALive - 3523 - Knights of the Round Table Time Limit: 4500 mSec Problem Description Input ...

  2. UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)

    由于互相憎恨的骑士不能相邻,把可以相邻的骑士连上无向边,会议要求是奇数,问题就是求不在任意一个简单奇圈上的结点个数. 如果不是二分图,一定存在一个奇圈,同一个双连通分量中其它点一定可以加入奇圈.很明显 ...

  3. uvalive 3523 Knights of the Round Table 圆桌骑士(强连通+二分图)

    题目真心分析不出来.看了白书才明白,不过有点绕脑. 容易想到,把题目给的不相邻的关系,利用矩阵,反过来建图.既然是全部可行的关系,那么就应该能画出含奇数个点的环.求环即是求双连通分量:找出所有的双连通 ...

  4. UVALive 3523 : Knights of the Round Table (二分图+BCC)

    题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; ; int n,m; int dfn[maxn],low[ ...

  5. [POJ2942]:Knights of the Round Table(塔尖+二分图染色法)

    题目传送门 题目描述 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: .相互憎恨的两个骑士不能坐在直接相邻的 ...

  6. uva 3523 Knights of the Round Table

    题意:给你n,m n为有多少人,m为有多少组关系,每组关系代表两人相互憎恨,问有多少个骑士不能参加任何一个会议. 白书算法指南 对于每个双联通分量,若不是二分图,就把里面的节点标记 #include ...

  7. Spoj 2878 KNIGHTS - Knights of the Round Table | 双联通分量 二分图判定

    题目链接 考虑建立原图的补图,即如果两个骑士不互相憎恨,就在他们之间连一条无向边. 显而易见的是,如果若干个骑士在同一个点数为奇数的环上时,他们就可以在一起开会.换句话说,如果一个骑士被一个奇环包含, ...

  8. 【LA3523】 Knights of the Round Table (点双连通分量+染色问题?)

    Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...

  9. POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]

    Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 12439   Acce ...

随机推荐

  1. NGUI基本事件

    You can add the following functions to your scripts placed on widgets or in-game objects with a coll ...

  2. Windows 配置安卓环境变量

    变量名:JAVA_HOME 变量值:JDK 路径 变量名:CLASSPATH 变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\toos.jar      // ...

  3. loadrunner配置多台负载机设置

    面对并发量比较大的性能需求,用单台机子进行加压由于本身硬件资源.网络资源等的限制已经不能满足该性能测试条件,这个时候就需要在场景中添加多台负载机来联机做性能测试.添加多台负载机的设置非常简单下面做一个 ...

  4. 什么是Socket?简单点,通俗易懂的?

    网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP的封装 ...

  5. java内存空间

    Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java在内存分配方面的知识.一般 ...

  6. JS等比例缩放图片,限定最大宽度和最大高度

    JS等比例缩放图片,限定最大宽度和最大高度 JavaScript //图片按比例缩放 var flag=false; function DrawImage(ImgD,iwidth,iheight){ ...

  7. Spring Tomcat启动过程

    入口,配置再web.xml中, 初始化applicationContext 创建webApplicationContext,这里可加载web.xml文件中定义了contextClass 获取conte ...

  8. 20145310《Java程序设计》第3周学习总结

    20145310 <Java程序设计>第3周学习总结 教材学习内容总结 本周学习内容比较多,主要是第四第五章的学习. 第四章 类与对象 类是对象的设计图,对象是类的实例. 类(Class) ...

  9. 20145314郑凯杰 《Java程序设计》第9周学习总结 积极主动敲代码

    20145314郑凯杰 <Java程序设计>第9周学习总结 教材学习内容总结 第十六章 ①JDBC(Java DataBase Connectivity) 即java数据库连接,是一种用于 ...

  10. left4dead2 常用配置

    难度控制 z_difficulty [Easy, Normal, Hard, Impossible]