http://poj.org/problem?id=2942 (题目链接)

题意

  有n个骑士要去参加圆桌会议,他们将围成一圈,想要他们不打架,当且仅当参加圆桌会议的骑士数为奇数并且相邻的两个骑士不互相憎恨。现在给出m条骑士之间两两憎恨的关系,问有多少骑士无论在何种情况下都不能参加圆桌会议。

Solution

  思路到是很简单,先构出原图的补图,补图中每条边代表这两个骑士可以相邻。那么很显然,如果某一个骑士处于任意一个奇环中,那么他就可以参加会议。

  这个问题该怎么处理呢?我们用Tarjan求出点-双连通分量,对于每一个点双,通过黑白染色看是否存在奇环,若染色不成功,那么存在奇环,否则是偶环。

细节

  Tarjan真是恶心爆。。求点-双一定要存边,这样可以避免很多分类讨论。。。

代码

  1. // bzoj1013
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<cstdio>
  7. #include<vector>
  8. #include<cmath>
  9. #define LL long long
  10. #define inf 2147483640
  11. #define eps 1e-7
  12. #define Pi acos(-1.0)
  13. #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
  14. using namespace std;
  15. inline int gi() {
  16. int x=0,f=1;char ch=getchar();
  17. while (ch<'0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();}
  18. while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
  19. return x*f;
  20. }
  21.  
  22. const int maxn=1010,maxm=1000010;
  23. struct edge {int to,next;}e[maxm<<1];
  24. struct data {int u,v;}s[maxn];
  25. int vis[maxn],dfn[maxn],low[maxn],f[maxn][maxn],pos[maxn];
  26. int ind,cnt,top,n,m,num,p,id[maxn],head[maxn];
  27. vector<int> v[maxn];
  28.  
  29. void link(int u,int v) {
  30. e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;
  31. }
  32. void Init() {
  33. for (int i=1;i<=num;i++) v[i].clear();
  34. cnt=ind=top=num=0;
  35. memset(head,0,sizeof(head));
  36. memset(vis,0,sizeof(vis));
  37. memset(dfn,0,sizeof(dfn));
  38. memset(low,0,sizeof(low));
  39. memset(pos,0,sizeof(pos));
  40. memset(id,0,sizeof(id));
  41. memset(f,0,sizeof(f));
  42. }
  43. void Tarjan(int x,int fa) {
  44. dfn[x]=low[x]=++ind;
  45. for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa) {
  46. if (!dfn[e[i].to]) {
  47. s[++top]=(data){x,e[i].to};
  48. Tarjan(e[i].to,x);
  49. low[x]=min(low[x],low[e[i].to]);
  50. if (low[e[i].to]>=dfn[x]) {
  51. num++;
  52. while (1) {
  53. v[num].push_back(s[top].u);v[num].push_back(s[top].v);
  54. if (s[top].u==x && s[top].v==e[i].to) break;
  55. top--;
  56. }
  57. top--;
  58. }
  59. }
  60. else low[x]=min(low[x],dfn[e[i].to]);
  61. }
  62. }
  63. bool dfs(int x,int col) {
  64. id[x]=col;
  65. for (int i=head[x];i;i=e[i].next)
  66. if (pos[e[i].to]==p) {
  67. if (!id[e[i].to]) {
  68. if (!dfs(e[i].to,col^1)) return 0;
  69. }
  70. else if (id[e[i].to]==id[x]) return 0;
  71. }
  72. return 1;
  73. }
  74. void work(int x) {
  75. vis[x]=1;
  76. for (int i=head[x];i;i=e[i].next)
  77. if (!vis[e[i].to] && pos[e[i].to]==p) work(e[i].to);
  78. }
  79. int main() {
  80. while (1) {
  81. n=gi(),m=gi();
  82. if (!n && !m) break;
  83. Init();
  84. for (int x,y,i=1;i<=m;i++) {
  85. x=gi(),y=gi();
  86. f[x][y]=f[y][x]=1;
  87. }
  88. for (int i=1;i<=n;i++)
  89. for (int j=1;j<=n;j++) if (i!=j && !f[i][j]) link(i,j);
  90. for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan(i,0);
  91. for (p=1;p<=num;p++) {
  92. for (int j=0;j<v[p].size();j++) pos[v[p][j]]=p;
  93. if (!dfs(v[p][0],p*2)) work(v[p][0]);
  94. }
  95. int ans=0;
  96. for (int i=1;i<=n;i++) if (!vis[i]) ans++;
  97. printf("%d\n",ans);
  98. }
  99. return 0;
  100. }

  

【poj2942】 Knights of the Round Table的更多相关文章

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

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

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

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

  3. 【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)

    [POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS   Memory Limit: 65536K Total Su ...

  4. [POJ2942][LA3523]Knights of the Round Table

    [POJ2942][LA3523]Knights of the Round Table 试题描述 Being a knight is a very attractive career: searchi ...

  5. POJ2942 UVA1364 Knights of the Round Table 圆桌骑士

    POJ2942 洛谷UVA1364(博主没有翻墙uva实在是太慢了) 以骑士为结点建立无向图,两个骑士间存在边表示两个骑士可以相邻(用邻接矩阵存图,初始化全为1,读入一对憎恨关系就删去一条边即可),则 ...

  6. 【POJ 2942】Knights of the Round Table(点双连通分量,二分图染色)

    圆桌会议必须满足:奇数个人参与,相邻的不能是敌人(敌人关系是无向边). 求无论如何都不能参加会议的骑士个数.只需求哪些骑士是可以参加的. 我们求原图的补图:只要不是敌人的两个人就连边. 在补图的一个奇 ...

  7. 【洛谷 SP2878】Knights of the Round Table(双联通分量)

    先放这吧,没时间写,明天再补 "明天到了" 题目链接 题意:求不在任何奇环内的点的数量. Tarjan求点双联通分量,然后再染色判断是不是二分图就好了. 只是不懂为什么Tarjan ...

  8. POJ2942:Knights of the Round Table——题解

    http://poj.org/problem?id=2942 所写的tarjan练习题最难的一道. 说白了难在考得不是纯tarjan. 首先我们把仇恨关系处理成非仇恨关系的图,然后找双连通分量,在双连 ...

  9. 【POJ】2942 Knights of the Round Table(双连通分量)

    http://poj.org/problem?id=2942 各种逗.... 翻译白书上有:看了白书和网上的标程,学习了..orz. 双连通分量就是先找出割点,然后用个栈在找出割点前维护子树,最后如果 ...

随机推荐

  1. IntelliJ Idea14 创建Maven多模块项目

    Maven多模块项目的参考资料 Sonatype上的教程 http://books.sonatype.com/mvnex-book/reference/multimodule.html 在这个教程里, ...

  2. Linux socket多进程服务器框架一

    重点:socket共用方法中错误码的定义以及错误码的解析 底层辅助代码 //serhelp.h #ifndef _vxser #define _vxser #ifdef __cplusplus ext ...

  3. jQuery 之 Callback 实现

    在 js 开发中,由于没有多线程,经常会遇到回调这个概念,比如说,在 ready 函数中注册回调函数,注册元素的事件处理等等.在比较复杂的场景下,当一个事件发生的时候,可能需要同时执行多个回调方法,可 ...

  4. ubuntu 安装VmTool

    VM tools 是Vmware的一组工具.主要用于虚拟主机显示优化与调整,另外还可以方便虚拟主机与本机的交互,如允许共享文件夹,甚至可以直接从本机向虚拟主机拖放文件.鼠标无缝切换.显示分辨率调整等, ...

  5. SQL 性能调优日常积累

    我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为笔者学习.摘录.并汇总部分资料与大家分享! (1)选择最有效率的表名顺序(只在基于规则的优化器中有效) ORACLE 的解析器按照从右到左 ...

  6. 别再迷信 zepto 了

    希望网上公开课的老师们不要再讲移动端网页用zepto了,坑了无数鸟啊 ~~~. 1.自己/公司/项目组所写和所积累(网上下的)的js函数都是以jQuery插件的写法来写的,如果要换到zepto上的话那 ...

  7. iOS搜索附近的位置(类似微博朋友圈位置)

    说什么都是苍白的,直接上图~ 在某些情况下,我们需要获取用户周边的位置,来让用户选取.例如微信的朋友圈,在发一条朋友圈时可以选择地点,就是使用这样的功能. 基于以上的情况(其实也就是为了模仿微信),有 ...

  8. JVM内存管理------GC算法精解(五分钟让你彻底明白标记/清除算法)

    相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底理解标记/清除算法,不过倘若各位猿友不能在五分钟内 ...

  9. Ryu

    What's Ryu? Ryu is a component-based software defined networking framework. Ryu provides software co ...

  10. hihocoder 1260

    之前做过的oj, acm题目忘了很多了, 又要开始要刷题了, go on! #1260 : String Problem I 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描 ...