题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议。参会骑士至少有3个且有奇数个。

题目分析:在可以相邻的骑士之间连一条无向边,构成一张图G。则问题变成了有几个节点不在奇圈(有奇数个节点的圈)内,并且一个点在圈内最多出现一次。如果G不连通,应该对每一个分量分别求解。奇圈上的点一定在同一个双连通分量内,要找出所有的双连通分量。但是能构成二分图的双连通分量中一定没有奇圈,不能构成二分图的双连通分量中一定含有奇圈,并且分量中所有的点都在奇圈上,所有还要判断每一个双连通分量能不能构成二分图。

其实就是一道模板题。。。

代码如下:

  1. # include<iostream>
  2. # include<cstdio>
  3. # include<vector>
  4. # include<stack>
  5. # include<cstring>
  6. # include<algorithm>
  7. using namespace std;
  8.  
  9. const int maxn=1005;
  10. struct Edge
  11. {
  12. int u,v;
  13. Edge(int _u,int _v):u(_u),v(_v){}
  14. };
  15. stack<Edge>S;
  16. vector<int>G[maxn],bcc[maxn];
  17. int bcc_cnt,dfs_cnt,low[maxn],pre[maxn],odd[maxn],color[maxn],bccno[maxn],iscut[maxn],A[maxn][maxn];
  18.  
  19. int dfs(int u,int fa)
  20. {
  21. int lowu=pre[u]=++dfs_cnt;
  22. int child=0;
  23. for(int i=0;i<G[u].size();++i){
  24. int v=G[u][i];
  25. if(!pre[v]){
  26. S.push(Edge(u,v));
  27. ++child;
  28. int lowv=dfs(v,u);
  29. lowu=min(lowu,lowv);
  30. if(lowv>=pre[u]){///存在一个满足条件的v,便能说明u是割点。
  31. iscut[u]=1;
  32. bcc[++bcc_cnt].clear();
  33. while(1)
  34. {
  35. Edge x=S.top();
  36. S.pop();
  37. if(bccno[x.u]!=bcc_cnt){
  38. bcc[bcc_cnt].push_back(x.u);
  39. bccno[x.u]=bcc_cnt;
  40. }
  41. if(bccno[x.v]!=bcc_cnt){
  42. bcc[bcc_cnt].push_back(x.v);
  43. bccno[x.v]=bcc_cnt;
  44. }
  45. if(x.u==u&&x.v==v)
  46. break;
  47. }
  48. }
  49. }
  50. else if(pre[v]<pre[u]&&v!=fa){
  51. S.push(Edge(u,v));
  52. lowu=min(lowu,pre[v]);
  53. }
  54. }
  55. if(fa<0&&child==1)///根节点只有1个子节点时不是割点。
  56. iscut[u]=0;
  57. low[u]=lowu;
  58. return lowu;
  59. }
  60.  
  61. void find_bcc(int n)
  62. {
  63. memset(pre,0,sizeof(pre));
  64. memset(iscut,0,sizeof(iscut));
  65. memset(bccno,0,sizeof(bccno));
  66. dfs_cnt=bcc_cnt=0;
  67. for(int i=0;i<n;++i)
  68. if(!pre[i])
  69. dfs(i,-1);
  70. }
  71.  
  72. bool bipartite(int u,int b)
  73. {
  74. for(int i=0;i<G[u].size();++i){
  75. int v=G[u][i];
  76. if(bccno[v]!=b)
  77. continue;
  78. if(color[v]==color[u])
  79. return false;
  80. if(!color[v]){
  81. color[v]=3-color[u];
  82. if(!bipartite(v,b))
  83. return false;
  84. }
  85. }
  86. return true;
  87. }
  88.  
  89. int main()
  90. {
  91. int n,m,a,b;
  92. while(scanf("%d%d",&n,&m)&&(n+m))
  93. {
  94. memset(A,0,sizeof(A));
  95. for(int i=0;i<n;++i) G[i].clear();
  96. while(m--){
  97. scanf("%d%d",&a,&b);
  98. --a,--b;
  99. A[a][b]=A[b][a]=1;
  100. }
  101. for(int i=0;i<n;++i)
  102. for(int j=i+1;j<n;++j)
  103. if(!A[i][j])
  104. G[i].push_back(j),G[j].push_back(i);
  105.  
  106. find_bcc(n);
  107.  
  108. memset(odd,0,sizeof(odd));
  109. for(int i=1;i<=bcc_cnt;++i){
  110. memset(color,0,sizeof(color));
  111. for(int j=0;j<bcc[i].size();++j)
  112. bccno[bcc[i][j]]=i;
  113. int u=bcc[i][0];
  114. color[u]=1;
  115. if(!bipartite(u,i))
  116. for(int j=0;j<bcc[i].size();++j)
  117. odd[bcc[i][j]]=1;
  118. }
  119. int ans=n;
  120. for(int i=0;i<n;++i)
  121. if(odd[i])
  122. --ans;
  123. printf("%d\n",ans);
  124. }
  125. return 0;
  126. }

  

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. 实参相依查找[条款25]----《C++必知必会》

    名字空间对现代C++编程和设计有着深远的影响.其中有些影响直接而明显,例如using声明和using 指令以及采用名字空间作用域加以限定的名字.然而,名字空间还有一些在语法上不那么明显但任然很有基础. ...

  2. SQL Server去重和判断是否为数字——OBJECT_ID的使用

    sql 语句查询时去掉重复项: 使用 distinct 去掉重复项: 首先可以明确的看到存在重复的名字,那么接下来就让我们试试使用 distinct 去重吧. select distinct * fr ...

  3. Django 分页查询并返回jsons数据,中文乱码解决方法

    Django 分页查询并返回jsons数据,中文乱码解决方法 一.引子 Django 分页查询并返回 json ,需要将返回的 queryset 序列化, demo 如下: # coding=UTF- ...

  4. weblogic控制台部署web项目图解

    图解网址:http://jingyan.baidu.com/article/c74d6000650d470f6b595d72.html

  5. 基础知识总结之 jdk部分

    第一次安装jdk 按照操作走完  会出现 C:\Program Files\Java\jdk1.8.0_91 和 C:\Program Files\Java\jre1.8.0_91 两个目录 (平级目 ...

  6. 负载均衡技术在CDN中发挥着重要作用

    转载地址:http://www.qicaispace.com/gonggao/server/page01/info07.asp CDN是一个经策略性部署的整体系统,能够帮助用户解决分布式存储.负载均衡 ...

  7. 编写和运行简单的"Hello World"操作系统内核

    通常编写一个操作系统内核是一项浩大的工程.但我今天的目标是制作一个简单的内核,用比较方便的方法在虚拟机上验证它能够被grub装载和运行,并且可通过gdb进行调试,为接下去的工作创造一个基础环境. 首先 ...

  8. python 数据分析----matplotlib

    Matplotlib是一个强大的Python绘图和数据可视化的工具包. 安装方法:pip install matplotlib 引用方法:import matplotlib.pyplot as plt ...

  9. RocEDU.阅读.写作《乌合之众》(一)

    序言 作者在序言里主要论述了时代演变的内在原因,表明对群体进行研究的重要性,阐述了研究群体行为特征时的研究方法,并概述了群体的发展过程. 造成文明变革的唯一重要变化,是影响到思想.观念和信仰的变化.目 ...

  10. 20145322 《Java程序设计》第7周学习总结

    20145322何志威 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 如果使用JDK8的话,可以使用Lambda特性去除重复的信息. 在只有Lambda表达式的情况下,参 ...