题目链接:

poj2942

题意:

有n个人,能够开多场圆桌会议

这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置

且每场圆桌会议的人数仅仅能为奇书

问有多少人不能參加

解题思路:

首先构图,将全部的仇视关系视为一条边,最后再取已经得到的图的逆图,

这样图上连接的边就代表能够相邻而坐的关系

然后就是找奇圈了,首先就是要找图中的环(点双连通分量)

这个环为奇环的条件:不是二分图||这个环中的部分点属于其它奇环

这个推断能够通过将已找到的环进行dfs黑白染色推断

最后不在奇环内的总和即是答案

至于为什么要找的是点双连通分量而不是边双连通分量 能够试试这组数据:

6 8

1 4

1 5

1 6

2 4

2 5

2 6

3 6

4 5

0 0



得到的逆图是这种:

假设是电双连通分量(拆开割点)则分为(1 2 3)和(3 4 5 6)两部分

而假设是边双连通分量(去掉割边)则仅仅有(1 2 3 4  5 6 )一部分了

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define maxn 1050
  5. using namespace std;
  6. struct node{
  7. int to,next;
  8. }edge[2000500];
  9. int head[maxn],ss;
  10. int map[maxn][maxn];
  11.  
  12. int in[maxn],odd[maxn],temp[maxn];
  13. int color[maxn];
  14.  
  15. int dfn[maxn],low[maxn],num;
  16. int insta[maxn],sta[maxn],top;
  17. int n;
  18.  
  19. void init()
  20. {
  21. memset(dfn,0,sizeof(dfn));
  22. memset(head,-1,sizeof(head));
  23. memset(insta,0,sizeof(insta));
  24. memset(map,0,sizeof(map));
  25. memset(odd,0,sizeof(odd));
  26. top=num=ss=0;
  27. }
  28.  
  29. void addedge(int a,int b)
  30. {
  31. edge[ss]=(node){b,head[a]};
  32. head[a]=ss++;
  33. }
  34.  
  35. int dfs(int u,int c)
  36. {
  37. color[u]=c;
  38. for(int i=head[u];i!=-1;i=edge[i].next)
  39. {
  40. int v=edge[i].to;
  41. if(!in[v])
  42. continue;
  43. if(color[v]==c)
  44. return 1;
  45. else if(color[v])
  46. continue;
  47. else if(dfs(v,3-c))
  48. return 1;
  49. }
  50. return 0;
  51. }
  52.  
  53. void Tarjan(int u,int pre)
  54. {
  55. dfn[u]=low[u]=++num;
  56. insta[u]=1;
  57. sta[top++]=u;
  58. for(int i=head[u];i!=-1;i=edge[i].next)
  59. {
  60. int v=edge[i].to;
  61. if(v==pre)
  62. continue;
  63. if(!dfn[v])
  64. {
  65. Tarjan(v,u);
  66. low[u]=min(low[u],low[v]);
  67.  
  68. if(dfn[u]<=low[v])
  69. {
  70. int s=0,d=-1;
  71. memset(in,0,sizeof(in));
  72. while(d!=v) //注意是v 点双连通的还有一种写法,总之要注意割点能够属于多个连通分量
  73. {
  74. d=sta[--top];
  75. in[d]=1;
  76. insta[d]=0; //不能让u=0
  77. temp[s++]=d;
  78. }
  79. in[u]=1;
  80. memset(color,0,sizeof(color));
  81. if(dfs(u,1)) //黑白染色判定
  82. {
  83. odd[u]=1;
  84. while(s!=0)
  85. odd[temp[--s]]=1;
  86. }
  87. }
  88. }
  89. else if(insta[v])
  90. low[u]=min(low[u],dfn[v]);
  91. }
  92. }
  93.  
  94. void solve()
  95. {
  96. for(int i=1;i<=n;i++)
  97. if(!dfn[i])
  98. Tarjan(i,-1);
  99. int ans=0;
  100. for(int i=1;i<=n;i++)
  101. if(!odd[i])
  102. ans++;
  103. printf("%d\n",ans);
  104. }
  105.  
  106. int main()
  107. {
  108. // freopen("in.txt","r",stdin);
  109. int m,a,b;
  110. while(scanf("%d%d",&n,&m)&&(m+n))
  111. {
  112. init();
  113. while(m--)
  114. {
  115. scanf("%d%d",&a,&b);
  116. map[a][b]=map[b][a]=1;
  117. }
  118. for(int i=1;i<=n;i++)
  119. for(int j=1;j<=n;j++)
  120. if(i!=j&&!map[i][j]) //取逆图
  121. addedge(i,j);
  122. solve();
  123. }
  124. return 0;
  125. }

POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈的更多相关文章

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

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

  2. POJ2942 Knights of the Round Table 点双连通分量 二分图判定

    题目大意 有N个骑士,给出某些骑士之间的仇恨关系,每次开会时会选一些骑士开,骑士们会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件:1.任意相互憎恨的两个骑士不能相邻.2.开会人数为大于2的奇 ...

  3. poj 2942 Knights of the Round Table(点双连通分量+二分图判定)

    题目链接:http://poj.org/problem?id=2942 题意:n个骑士要举行圆桌会议,但是有些骑士相互仇视,必须满足以下两个条件才能举行: (1)任何两个互相仇视的骑士不能相邻,每个骑 ...

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

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

  5. [POJ2942]Knights of the Round Table(点双+二分图判定——染色法)

    建补图,是两个不仇恨的骑士连边,如果有环,则可以凑成一桌和谐的打麻将 不能直接缩点,因为直接缩点求的是连通分量,点双缩点只是把环缩起来 普通缩点                             ...

  6. UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)

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

  7. poj2942 Knights of the Round Table[点双+二分图染色]

    首先转化条件,把无仇恨的人连边,然后转化成了求有哪些点不在任何一个奇环中. 一个奇环肯定是一个点双,所以想到处理出所有点双,但是也可能有的点双是一个偶环,有的可能是偶环和奇环混杂,不好判. 考察奇环性 ...

  8. POJ 2942 Knights of the Round Table(双连通分量)

    http://poj.org/problem?id=2942 题意 :n个骑士举行圆桌会议,每次会议应至少3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置.如果意见发生分歧,则需要举手表决,因此 ...

  9. POJ2942 Knights of the Round Table(点双连通分量 + 二分图染色)

    题目大概说要让n个骑士坐成一圈,这一圈的人数要是奇数且大于2,此外有些骑士之间有仇恨不能坐在一起,问有多少个骑士不能入座. 双连通图上任意两点间都有两条不重复点的路径,即一个环.那么,把骑士看做点,相 ...

随机推荐

  1. RabbitMQ的简单应用

    虽然后台使用了读写分离技术,能够在一定程度上抗击高并发,但是如果并发量特别巨大时,主数据库不能同时处理高并发的请求,这时数据库容易宕机. 问题: 现在的问题是如何既能保证数据库正常运行,又能实现用户数 ...

  2. Django 入门案例开发(下)——创建项目应用及模型类

    前面两章是在已经开发好的项目上用来描述环境和业务,这一章创建一个全新的项目来用作开发,你可以跟着我的步骤进行开发,如果有不理解的地方可以给我留言. 今天的任务是创建好项目和用户(users)应用及让它 ...

  3. CentOS下安装Tomcat 8

    CentOS下安装Tomcat 8 安装Tomcat8 去http://tomcat.apache.org/download-80.cgi下载Tomcat8的安装文件apache-tomcat-8.0 ...

  4. LKD: Chapter 6 Kernel Data Structures

    这一章我们研究四种主要的数据结构: linked lists, queues, maps, binary trees. Linked Lists:(<linux/list.h>) 在lin ...

  5. shiro入门示例

    一.pom引入maven依赖 <dependencies> <dependency> <groupId>junit</groupId> <arti ...

  6. laravel中with()方法,has()方法和whereHas()方法的区别

    with() with()方法是用作"渴求式加载"的,那主要意味着,laravel将会伴随着主要模型预加载出确切的的关联关系.这就对那些如果你想加在一个模型的所有关联关系非常有帮助 ...

  7. RandomAccessFile多线程下载、复制文件、超大文件读写

    最近在准备面试,翻了翻自己以前写的Demo,发现自己写了不少的工具包,今天整理了一下,分享给大家. 本文包含以下Demo: 1.常用方法测试 2.在文件中间插入一段新的数据 3.多线程下载文件 4.多 ...

  8. C语言中静态申请内存遇到的错误分析

    今天调试代码中,遇到了一个比较奇怪的打印,dump出来的数据只有前四位有值,其他后面的都为零. 出于直觉,应该是内存没有申请到.仔细核对代码之后,果真发现了一个语法错误,就是使用指针的指针时 ,对申请 ...

  9. 一次php涉及跨域功能的麻烦及解决方案

    一,功能及描述 1,在后台管理网站(php)admin.xxx.com(以下简称admin),上拉取并编辑aaa.xxx.com(php,以下简称aaa)上的图片及文件 2,file_get_cont ...

  10. Less运算和函数

    Less运算和函数   Less运算 在我们的 CSS 中,充斥着大量数值型的 value,比如 color.padding.margin 等.在某些情况下,这些数值之间是有着一定关系的,那么我们怎样 ...