题目链接

题意及题解参见lrj训练指南

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int maxn=1e3+;
  5. int n,m;
  6. int dfn[maxn],low[maxn],time_tag;
  7. int bccno[maxn],bcc_cnt;
  8. int iscut[maxn];
  9. int A[maxn][maxn];
  10. vector<int> adj[maxn];
  11. vector<int> bcc[maxn];
  12. int odd[maxn];
  13. struct Edge
  14. {
  15. int u,v;
  16. Edge() {}
  17. Edge(int u_,int v_)
  18. {
  19. u=u_,v=v_;
  20. }
  21. };
  22. stack<Edge> st;
  23. void init()
  24. {
  25. memset(A,,sizeof(A));
  26. memset(dfn,,sizeof(dfn));
  27. memset(iscut,,sizeof(iscut));
  28. memset(bccno,,sizeof(bccno));
  29. memset(odd,,sizeof(odd));
  30. for(int i=; i<=n; i++)
  31. adj[i].clear(),bcc[i].clear();
  32. bcc_cnt=time_tag=;
  33. }
  34. void dfs(int u,int pre)
  35. {
  36. low[u]=dfn[u]=++time_tag;
  37. int child=; //子节点数目
  38. for(int v:adj[u])
  39. {
  40. if(v==pre) continue;
  41. if(!dfn[v]) // 把dfn[]当vis[]使用
  42. {
  43. st.push(Edge(u,v));
  44. child++;
  45. dfs(v,u);
  46. low[u]=min(low[u],low[v]);
  47. if(low[v]>=dfn[u])
  48. {
  49. iscut[u]=;
  50. bcc_cnt++;
  51. while()
  52. {
  53. Edge x=st.top();st.pop();
  54. if(bccno[x.u]!=bcc_cnt) bcc[bcc_cnt].push_back(x.u),bccno[x.u]=bcc_cnt;
  55. if(bccno[x.v]!=bcc_cnt) bcc[bcc_cnt].push_back(x.v),bccno[x.v]=bcc_cnt;
  56. if(x.u==u&&x.v==v) break;
  57. }
  58. }
  59. }
  60. else if(dfn[v]<dfn[u])
  61. {
  62. st.push(Edge(u,v));
  63. low[u]=min(low[u],dfn[v]);
  64. }
  65. }
  66. if(pre<&&child==) iscut[u]=; //只有一个孩子的根节点
  67. }
  68. void find_bcc()
  69. {
  70. for(int i=;i<n;i++)
  71. if(!dfn[i]) dfs(i,-);
  72. }
  73.  
  74. int color[maxn];
  75. //判定结点u所在的连通分量是否为二分图
  76. bool bipartite(int u,int tag)
  77. {
  78. for(int v:adj[u])
  79. {
  80. if(bccno[v]!=tag) continue;
  81. if(color[v]==color[u]) return false;
  82. if(!color[v])
  83. {
  84. color[v]=-color[u];
  85. if(!bipartite(v,tag)) return false;
  86. }
  87. }
  88. return true;
  89. }
  90.  
  91. int main()
  92. {
  93. while(scanf("%d%d",&n,&m)>&&n)
  94. {
  95. init();
  96. for(int i=;i<m;i++)
  97. {
  98. int u,v;
  99. scanf("%d%d",&u,&v);
  100. u--,v--;
  101. A[u][v]=A[v][u]=;
  102. }
  103. for(int u=;u<n;u++)
  104. for(int v=u+;v<n;v++)
  105. if(!A[u][v]) adj[u].push_back(v),adj[v].push_back(u);
  106. find_bcc();
  107. for(int i=;i<=bcc_cnt;i++)
  108. {
  109. memset(color,,sizeof(color));
  110. for(int u:bcc[i]) bccno[u]=i;
  111. int u=bcc[i][];
  112. color[u]=;
  113. if(!bipartite(u,i))
  114. for(int v:bcc[i]) odd[v]=;
  115. }
  116. int ans=n;
  117. for(int i=;i<n;i++) if(odd[i]) ans--;
  118. printf("%d\n",ans);
  119. }
  120. }

UVALive 3523 : Knights of the Round Table (二分图+BCC)的更多相关文章

  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. uva 3523 Knights of the Round Table

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

  5. 【POJ2942】Knights of the Round Table(二分图 点双联通分量)

    题目链接 大意 给定\(N\)个点与\(M\)个关系,每个关系表示某两个点间没有直接的边相连,求不在所有奇环上的点的个数. (\(1\le N\le 1e3,1\le M\le 1e6\)) 思路 考 ...

  6. UVAlive3523 Knights of the Round Table(bcc)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18122 [思路] 点-双连通分量 求出bcc,判断每个bcc是否为 ...

  7. UVA-1364.Knights of the Round Table 无向图BCC

    题目链接:https://vjudge.net/problem/UVA-1364 题意:有n个人参加会议,互相憎恨的人不能坐在相邻的位置,并且每个会议参加的人数必须是奇数,求有多少个人不能参加任何一个 ...

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

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

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

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

随机推荐

  1. windows上使用curl删除和查看ES索引

    首先使用curl获取集群中可用的Elasticsearch索引列表: $ curl http://<node-ip|hostname>:9200/_cat/indices <node ...

  2. 描述什么是springboot

    Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作<Expert One-On-One J2EE Developme ...

  3. C#程序员经常用到的10个实用代码片段 - 操作系统

    原文地址  如果你是一个C#程序员,那么本文介绍的10个C#常用代码片段一定会给你带来帮助,从底层的资源操作,到上层的UI应用,这些代码也许能给你的开发节省不少时间.以下是原文: 1 读取操作系统和C ...

  4. python 并发编程 多线程 线程理论

    操作系统比作一家公司,进程相当于一个部门  线程相当于一个部门的成员 进程之间是互相隔离的 一 什么是线程 1. 每启动一个进程 至少有一个线程,  在传统操作系统中,每个进程有一个地址空间,而且默认 ...

  5. 常用DOS命令及编程软件fa

    1.常用的dos命令(应用) 在接触集成开发环境之前,我们需要使用命令行窗口对Java程序进行编译和运行,所以需要知道dos命令. 打开命令行窗口的方式:win + r打开运行窗口对java程序进行编 ...

  6. ucloud建新主机

    系统盘默认20G,可调到40不增加费用.需建好主机后关机才能更改. root密码按统一的设 设好主机名,选好分组

  7. [转帖].NET Core单文件发布静态编译AOT CoreRT

    .NET Core单文件发布静态编译AOT CoreRT https://www.cnblogs.com/linezero/p/CoreRT.htm .NET Core单文件发布静态编译AOT Cor ...

  8. redis内存满了怎么办?

    redis最为缓存数据库,一般用于存储缓存数据,用于缓解数据库压力,但是缓存太多,内存满了怎么办呢.一般有以下几种方法 一.增加内存 redis存储于内存中,数据太多,占用太多内存,那么增加内存就是最 ...

  9. C++ Primer: 1. 初识输入和输出

    C++没有定义任何的输入和输出语句,而是使用了 标准库来提供IO机制---iostream; 标准库iostream定义了4种不同的IO对象: cin:     标准输入对象:instream类型的对 ...

  10. centos中安装python3.7

    1.1 CentOS 7编译安装Python3.7.X 1.安装依赖&下载python3.7 # 1.yum更新yum源 yum update # 2.安装Python 3.7所需的依赖否则安 ...