POJ2942 UVA1364 Knights of the Round Table 圆桌骑士
POJ2942 洛谷UVA1364(博主没有翻墙uva实在是太慢了)
以骑士为结点建立无向图,两个骑士间存在边表示两个骑士可以相邻(用邻接矩阵存图,初始化全为1,读入一对憎恨关系就删去一条边即可),则题意变为求图中不在任何奇环(结点数为奇数的环)中的点的数量。
一个环上的点一定属于一个双连通分量(两两都有两条路径可达)
那么什么时候双连通分量中没有奇环呢?
显然,当双连通分量是二分图的时候,图中没有奇环,因为从一个点出发回到该点一定要经过偶数条边。
即非二分图的双连通分量一定含有奇环
那么,非二分图的双连通分量的每个点是否都在奇环中呢?
假设v,u1,u2属于同一个双连通分量,且已知u1,u2在奇环上。求证:v也在奇环上
因为u1,u2在奇环上,所以u1,u2在环上的两条路径一条长度为奇数,一条长度为偶数。故无论u1-v-u2的长度为奇数或偶数都可以以v,u1,u2构造一个奇圈
所以我们得到非二分图的双连通分量中的每个点都在奇环上
那么我们的任务就转换为求无向图中是二分图的双连通分量中点的个数
有了上面的分析,代码实现就很简单了
- #include<cstdio>
- #include<cctype>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- #define re register int
- int graph[][];//邻接矩阵
- int dfn[],dfs_clock,n,m,stack[],top,ans,queue[],left,right,color[];
- int bccno[],bcc_cnt,tot;//各个点bcc编号、当前bcc编号、bcc结点数目
- bool odd[];//每个点是否在奇圈上
- int read()
- {
- int f=,x=;
- char c=getchar();
- while(!isdigit(c))
- {
- f=f|c=='-';
- c=getchar();
- }
- while(isdigit(c))
- {
- x=(x<<)+(x<<)+(c^);
- c=getchar();
- }
- return x;
- }
- bool bipartite(int x)//二分图判定
- {
- memset(color,,sizeof(color));
- left=right=;
- queue[]=x;
- color[x]=;
- while(right>=left)
- {
- int u=queue[left++];
- for(re v=;v<=n;v++)
- {
- if(graph[u][v]&&bccno[v]==bcc_cnt)
- {
- if(color[v]==color[u])
- return false;
- else if(!color[v])
- {
- queue[++right]=v;
- color[v]=^color[u];
- }
- }
- }
- }
- return true;
- }
- int tarjan(int u,int fa)//求双连通分量
- {
- int lowu=dfn[u]=++dfs_clock;
- for(re v=;v<=n;v++)
- if(graph[u][v])
- {
- if(!dfn[v])
- {
- stack[++top]=v;
- int lowv=tarjan(v,u);
- lowu=min(lowu,lowv);
- if(lowv>=dfn[u])
- {
- tot=;
- bcc_cnt++;
- while(stack[top]!=v)
- {
- tot++;
- bccno[stack[top--]]=bcc_cnt;
- }
- tot+=;
- bccno[stack[top--]]=bccno[u]=bcc_cnt;//割点不出栈
- if(!bipartite(u))//不是二分图,则此BCC中的点均在奇圈上
- for(re i=;i<=n;i++)
- if(bccno[i]==bcc_cnt)
- odd[i]=true;
- }
- }
- else if(v!=fa)
- lowu=min(lowu,dfn[v]);
- }
- return lowu;
- }
- void reset()
- {
- memset(bccno,,sizeof(bccno));
- memset(dfn,,sizeof(dfn));
- memset(odd,,sizeof(odd));
- dfs_clock=bcc_cnt=ans=top=;
- for(re i=;i<=n;i++)
- for(re j=;j<=n;j++)
- graph[i][j]=;
- for(re i=;i<=n;i++)
- graph[i][i]=;
- }
- int main()
- {
- while((n=read())&&(m=read()))
- {
- reset();
- while(m--)
- {
- int u=read(),v=read();
- graph[u][v]=graph[v][u]=;
- }
- for(re i=;i<=n;i++)
- if(!dfn[i])
- {
- stack[++top]=i;
- tarjan(i,i);
- }
- for(re i=;i<=n;i++)
- if(!odd[i])
- ans++;
- printf("%d\n",ans);
- }
- return ;
- }
Knights of the Round Table 圆桌骑士
POJ2942 UVA1364 Knights of the Round Table 圆桌骑士的更多相关文章
- poj 2942 Knights of the Round Table 圆桌骑士(双连通分量模板题)
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 9169 Accep ...
- uvalive 3523 Knights of the Round Table 圆桌骑士(强连通+二分图)
题目真心分析不出来.看了白书才明白,不过有点绕脑. 容易想到,把题目给的不相邻的关系,利用矩阵,反过来建图.既然是全部可行的关系,那么就应该能画出含奇数个点的环.求环即是求双连通分量:找出所有的双连通 ...
- KNIGHTS - Knights of the Round Table 圆桌骑士 点双 + 二分图判定
---题面--- 题解: 考场上只想到了找点双,,,,然后不知道怎么处理奇环的问题. 我们考虑对图取补集,这样两点之间连边就代表它们可以相邻, 那么一个点合法当且仅当有至少一个大小至少为3的奇环经过了 ...
- UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
由于互相憎恨的骑士不能相邻,把可以相邻的骑士连上无向边,会议要求是奇数,问题就是求不在任意一个简单奇圈上的结点个数. 如果不是二分图,一定存在一个奇圈,同一个双连通分量中其它点一定可以加入奇圈.很明显 ...
- [POJ2942][LA3523]Knights of the Round Table
[POJ2942][LA3523]Knights of the Round Table 试题描述 Being a knight is a very attractive career: searchi ...
- UVA-1364.Knights of the Round Table 无向图BCC
题目链接:https://vjudge.net/problem/UVA-1364 题意:有n个人参加会议,互相憎恨的人不能坐在相邻的位置,并且每个会议参加的人数必须是奇数,求有多少个人不能参加任何一个 ...
- 【poj2942】 Knights of the Round Table
http://poj.org/problem?id=2942 (题目链接) 题意 有n个骑士要去参加圆桌会议,他们将围成一圈,想要他们不打架,当且仅当参加圆桌会议的骑士数为奇数并且相邻的两个骑士不互相 ...
- POJ2942:Knights of the Round Table——题解
http://poj.org/problem?id=2942 所写的tarjan练习题最难的一道. 说白了难在考得不是纯tarjan. 首先我们把仇恨关系处理成非仇恨关系的图,然后找双连通分量,在双连 ...
- 【POJ2942】Knights of the Round Table(二分图 点双联通分量)
题目链接 大意 给定\(N\)个点与\(M\)个关系,每个关系表示某两个点间没有直接的边相连,求不在所有奇环上的点的个数. (\(1\le N\le 1e3,1\le M\le 1e6\)) 思路 考 ...
随机推荐
- java dwg转svg
package com.example.demo.dxf2svg; import com.aspose.cad.InterpolationMode; import com.aspose.cad.Smo ...
- WebMvcConfigurerAdapter详解和过时后的替代方案
一.什么是WebMvcConfigurerAdapter Spring内部的一种配置方式采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制 二.WebMvcConfigur ...
- zstack分配的虚拟机的dns设置
环境: $ uname -a Linux 10-57-19-61 2.6.32-504.el6.x86_64 #1 SMP Wed Oct 15 04:27:16 UTC 2014 x86_64 x8 ...
- 【DSP开发】【Linux开发】基于ARM+DSP进行应用开发
针对当前应用的复杂性,SOC芯片更好能能满足应用和媒体的需求,集成众多接口,用ARM做为应用处理器进行多样化的应用开发和用户界面和接口,利用DSP进行算法加速,特别是媒体的编解码算法加速,既能够保持算 ...
- 【Qt开发】如何将内存图像数据封装成QImage V1
如何将内存图像数据封装成QImage 当采用Qt开发相机数据采集软件时,势必会遇到采集内存图像并进行处理(如缩放.旋转)操作.如果能够将内存图像数据封装成QImage,则可以利用QImage强大的图像 ...
- 获取kafka最新offset-scala
无论是在spark streaming消费kafka,或是监控kafka的数据时,我们经常会需要知道offset最新情况 kafka数据的topic基于分区,并且通过每个partition的主分区可以 ...
- Apache 强制SSL访问
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R ...
- 《剑指offer》面试题27 二叉搜索树与双向链表 Java版
(将BST改成排序的双向链表.) 我的方法一:根据BST的性质,如果我们中序遍历BST,将会得到一个从小到大排序的序列.如果我们将包含这些数字的节点连接起来,就形成了一个链表,形成双向链表也很简单.关 ...
- c语言中字符串跨行书写的问题
字符串常量定义时的换行问题 如果我们在一行代码的行尾放置一个反斜杠,c语言编译器会忽略行尾的换行符,而把下一行的内容也算作是本行的内容.这里反斜杠起到了续行的作用. 如果我们不使 ...
- anconda下安装opencv
提示:如果你安装了python其它版本,或者在anaconda中创建了虚拟环境,应该先激活你的环境,然后再在命令窗口执行下面的操作 1.首先下载所需镜像文件: 我们需要上网站去下载我们需要的版本. 官 ...