【POJ2942】Knights of the Round Table(二分图 点双联通分量)
大意
给定\(N\)个点与\(M\)个关系,每个关系表示某两个点间没有直接的边相连,求不在所有奇环上的点的个数。
(\(1\le N\le 1e3,1\le M\le 1e6\))
思路
考虑到\(N\)比较小的缘故,我们不妨暴力连边。
对于现在得到的一个图,我们需要找出所有在奇环上的点。
考虑使用点双联通分量对图进行缩点,对于每个点双分量,暴力的去判断它是否是二分图。
- ①如果是二分图,那么显然无奇环,对该点双上的点不做修改。
- ②如果不是二分图,那么对于这个点双联通分量,一定会有一个奇环, 而通过这个奇环一定可以使其他所有点在一个奇环上。
对于②情况的证明如下:
我们设有该点双分量上的某一段,使得两个端点都在该奇环上,显然每个点都会在至少一个这样的段上。
则连边关系分别是从该奇环上的某个奇段或偶段出发与图上的这一段形成环,则可以根据这一段的奇偶性与其对应的形成一个奇环。
(注:①情况不做修改是为了不覆盖②情况下处理出的答案,点双会重点)
(注:不用边双联通分量主要是为了让每个联通分量内部不存在两环只共一点的8字形)
代码
略丑,见谅
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1005;
const int MAXM=1000005;
int N,M,Cnt,Root=1;
int dfn[MAXN],low[MAXN];
vector<int>P[MAXN],T[MAXN];
int Anscnt,stac[MAXN],len;
vector<int>HP[MAXM];
void DFS(int u,int fad){
stac[++len]=u;
low[u]=dfn[u]=++Cnt;
int size=P[u].size();
for(int i=0;i<size;i++){
int v=P[u][i];
if(dfn[v]){
if(T[u][i]==fad)continue;
low[u]=min(low[u],dfn[v]);
continue;
}
DFS(v,T[u][i]);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
HP[++Anscnt].push_back(u);
while(1){
int x=stac[len--];
HP[Anscnt].push_back(x);
if(x==v)break;
}
}
}
}
void Add(int x,int y,int id){
P[x].push_back(y);
T[x].push_back(id);
P[y].push_back(x);
T[y].push_back(id);
}
int Vis[MAXN],Col[MAXN];
int KM[MAXN][MAXN];
int ans[MAXN],Ans;
int Check(int u){
Vis[u]=1;
int size=P[u].size();
for(int i=0;i<size;i++){
int v=P[u][i];
if(Vis[v]==-1)continue;
if(Vis[v]){
if(Col[v]==Col[u])
return 1;
continue;
}
Col[v]=(Col[u]+1)%2;
if(Check(v))return 1;
}
return 0;
}
void Init(){
memset(Vis,-1,sizeof(Vis));
memset(Col,0,sizeof(Col));
for(int i=1;i<=Anscnt;i++){
int size=HP[i].size();
for(int j=0;j<size;j++)
Vis[HP[i][j]]=0;
if(size){
if(Check(HP[i][0])){
for(int j=0;j<size;j++)
ans[HP[i][j]]=1;
}
}
for(int j=0;j<size;j++)
Vis[HP[i][j]]=-1,Col[HP[i][j]]=0;
}
}
void clear(){
Cnt=len=0;
for(int i=1;i<=N;i++){
ans[i]=0;Col[i]=0;
dfn[i]=low[i]=stac[i]=0;
P[i].clear(),T[i].clear();
for(int j=1;j<=N;j++)
KM[i][j]=0;
}
for(int i=1;i<=Anscnt;i++)HP[i].clear();
N=M=Anscnt=Ans=0;
}
int main(){
while(~scanf("%d%d",&N,&M)&&N&&M){
for(int i=1,x,y;i<=M;i++){
scanf("%d%d",&x,&y);
KM[x][y]=KM[y][x]=1;
}M=0;
for(int i=1;i<=N;i++)
for(int j=i+1;j<=N;j++)
if(!KM[i][j])Add(i,j,++M);
for(int i=1;i<=N;i++)
if(!dfn[i])DFS(i,0);
Init();
for(int i=1;i<=N;i++)
if(!ans[i])Ans++;
printf("%d\n",Ans);
clear();
}
return 0;
}
/*
5 5
1 4
1 5
2 5
3 4
4 5
5 5
1 4
1 5
2 5
3 4
4 5
5 5
1 4
1 5
2 5
3 4
4 5
0 0
*/
【POJ2942】Knights of the Round Table(二分图 点双联通分量)的更多相关文章
- POJ2942 Knights of the Round Table(点双连通分量 + 二分图染色)
题目大概说要让n个骑士坐成一圈,这一圈的人数要是奇数且大于2,此外有些骑士之间有仇恨不能坐在一起,问有多少个骑士不能入座. 双连通图上任意两点间都有两条不重复点的路径,即一个环.那么,把骑士看做点,相 ...
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 12439 Acce ...
- POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】
LINK 题目大意 有一群人,其中有一些人之间有矛盾,现在要求选出一些人形成一个环,这个环要满足如下条件: 1.人数大于1 2.总人数是奇数 3.有矛盾的人不能相邻 问有多少人不能和任何人形成任何的环 ...
- 「题解」:[POJ2942]Knights of the Round Table
问题 E: Knights of the Round Table 时间限制: 1 Sec 内存限制: 256 MB 题面 题目描述 作为一名骑士是一个非常有吸引力的职业:寻找圣杯,拯救遇难的少女,与 ...
- 【LA3523】 Knights of the Round Table (点双连通分量+染色问题?)
Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...
- POJ 2942Knights of the Round Table(二分图判定+双连通分量)
题目链接 题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. ...
- UVA 1364 - Knights of the Round Table (获得双连接组件 + 二部图推理染色)
尤其是不要谈了些什么,我想A这个问题! FML啊.....! 题意来自 kuangbin: 亚瑟王要在圆桌上召开骑士会议.为了不引发骑士之间的冲突. 而且可以让会议的议题有令人惬意的结果,每次开会前都 ...
- poj2942 Knights of the Round Table,无向图点双联通,二分图判定
点击打开链接 无向图点双联通.二分图判定 <span style="font-size:18px;">#include <cstdio> #include ...
- POJ2942 Knights of the Round Table 点双连通分量 二分图判定
题目大意 有N个骑士,给出某些骑士之间的仇恨关系,每次开会时会选一些骑士开,骑士们会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件:1.任意相互憎恨的两个骑士不能相邻.2.开会人数为大于2的奇 ...
随机推荐
- openmesh - src - trimesh delete and add elements
openmesh - src - trimesh delete and add elements openmesh 版本 8.1 About 本文主要介绍openmesh的如下接口 add_verte ...
- GDB调试-从入门到实践
你好,我是雨乐! 在上篇文章中,我们分析了线上coredump产生的原因,其中用到了coredump分析工具gdb,这几天一直有读者在问,能不能写一篇关于gdb调试方面的文章,今天借助此文,分享一些工 ...
- MyBatis 一级缓存实现详解及使用注意事项
一级缓存介绍 在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对 ...
- 03.python封装与解构
封装与结构 基本概念 t1 = 1, 2 print(type(t1)) # 什么类型 t2 = (1, 2) print(type(t2)) Python等式右侧出现逗号分隔的多值的时候,就会将这几 ...
- Flask_环境部署(十六)
flask自带的服务器,无法满足性能要求,我们这里采用Gunicorn做wsgi容器,来部署flask程序并使用 Nginx 做前端代理实现分流.转发.负载均衡,以及分担服务器的压力. Gunicor ...
- MySQL删除数据库或表(DROP DATABASE/table语句)
DROP DATABASE [ IF EXISTS ] <数据库名> DROP table[ IF EXISTS ] <数据库表名> 语法说明如下: <数据库名>: ...
- 长安“战疫”网络安全卫士守护赛writeup
一. 解题情况 二. 解题过程 题目一 八卦迷宫 用画图工具手工连接,然后将路上的图表和字相对应 按顺序打出,然后根据题目要求换成全拼,加上图片里的前缀cazy{}提交 flag为: cazy{zha ...
- Redis内存分析工具之redis-rdb-tools的安装与使用
操作系统:Centos7 1.redis-rdb-tools工具是用python语言编写的,所以首先需要安装python: 安装: (1)用 wget 下载 python 2.7 并解压( 如果 ...
- jmu-ds-舞伴问题
假设在周末舞会上,男士和女士们分别进入舞厅,各自排成一队.跳舞开始,依次从男队和女队队头各出一人配成舞伴,若两队初始人数不同,则较长那一队未配对者等待下一轮舞曲.现要求写一算法模拟上述舞伴配对问题. ...
- 18个示例详解 Spring 事务传播机制(附测试源码)
什么是事务传播机制 事务的传播机制,顾名思义就是多个事务方法之间调用,事务如何在这些方法之间传播. 举个例子,方法 A 是一个事务的方法,方法 A 执行的时候调用了方法 B,此时方法 B 有无事务以及 ...