【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的奇 ...
随机推荐
- css基础-1
css简介 一.CSS 指层叠样式表 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解决内容与表现分离的问题 外部样式表可以极大提高工作效率 外部 ...
- JMeter跨线程,怎么定义全局变量,跨线程使用变量?
JMeter跨线程时,怎么定义全局变量,跨线程使用此变量? 通过函数助手,获取到设置变量的语法脚本 2.通过Bean shell Sampler取样器,定义全局变量 3.定义好全局变量,可以调用,调用 ...
- JMeter_分布式压测配置
前置条件 电脑A,电脑B,电脑C均安装相同版本的JMeter 和JDK.其中电脑A作为控制机,电脑B和电脑C作为施压机 电脑A IP:172.16.0.114 电脑B IP:172.16.0.115 ...
- Vue系列教程(三)之vue-cli脚手架的使用
一.Vue-cli的环境准备 目的:(1)快速管理依赖 (2)确定项目结构 1.安装node.js Node.js是一个可以让前端运行在服务器上的一个工. 下载:https://nodejs.org/ ...
- Object.keys()方法 返回对象属性数组
MDN语法 Object.keys(obj) 参数obj:要返回其枚举自身属性的对象. 返回值:一个表示给定对象的所有可枚举属性的字符串数组. 1.传入一个对象,返回的的是所有属性值 var obj2 ...
- 接口神器之 Json Server 详细指南
简介 json-server 是一款小巧的接口模拟工具,一分钟内就能搭建一套 Restful 风格的 api,尤其适合前端接口测试使用. 只需指定一个 json 文件作为 api 的数据源即可,使用起 ...
- Centos下安装Maven私服Nexus
dockers安装Nexus,指定访问路径(默认为/:在使用Nginx做反向代理时,最好指定访问路径),并在容器外持久化数据,避免Nexus容器升级后数据丢失. 安装并启动 docker run -d ...
- day 9 scanf输入和gets输入的区别
(1).计算机高级语言程序运行方法有编译执行和编译解释两种,一下叙述中正确的是[A] A.C语言程序仅可以编译执行 B.C语言程序仅可以解释执行 C.C语言程序既可以编译执行又可以解释执行 D.以上说 ...
- VUE3 之 组件传参
1. 概述 韦奇定律告诉我们:大部分人都很容易被别人的话所左右,从而开始动摇.怀疑,最终迷失自我.因此我们要努力的坚定信念,相信自己,才不会被周围的环境所左右,才能取得最终的胜利. 言归正传,之前我们 ...
- go面试题-基础类
go基础类 1. go优势 * 天生支持并发,性能高 * 单一的标准代码格式,比其它语言更具可读性 * 自动垃圾收集比java和python更有效,因为它与程序同时执行 go数据类型 int stri ...