【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的奇 ...
随机推荐
- Jedis 连接池的基本使用
jedis直连 每次操作都会创建一个jedis对象,执行完毕后关闭连接后释放,对应的就是一次Tcp连接. jedis连接池 预先生成一批jedis连接对象放入连接池中,当需要对redis进行操作时从连 ...
- 数三角count(归类)
评测方式:文本比较 题目描述 这是一个数三角的游戏.长度为1或SQRT(2)的小木棍放在一个网格上.如图所示,有水平的,垂直的或对角的.对角放置的木棍可以交叉. avatar 将木棍随意地放在网格上得 ...
- 第三代微服务架构:基于 Go 的博客微服务实战案例,支持分布式事务
这是一个可一键部署在 Kubernetes-Istio 集群中的,基于 Golang 的博客微服务 Demo,支持分布式事务. 项目地址:https://github.com/jxlwqq/blog- ...
- 04.python哈希表
python哈希表 集合Set 集合,简称集.由任意个元素构成的集体.高级语言都实现了这个非常重要的数据结构类型. Python中,它是可变的.无序的.不重复的元素的集合. 初始化 set() -&g ...
- update sql时,常记错同时更新多个参数用and,正确是用逗号
记录一下,经常记错的一个点,在update多个参数时,多个参数之间用and连接,这个时候,语句就会报错了 其实,正确的是用逗号隔开, 使用SQL中的update更新多个字段值,set后面的条件要用逗号 ...
- CentOS 系统 查看 cpu核数
转载自 :Centos下查看cpu核数 - 韩憨 - 博客园 (cnblogs.com) 1.概念物理CPU:实际Server中插槽上的CPU个数.物理cpu数量:可以数不重复的 physical i ...
- Jenkins_忘记管理员密码的处理方法
1.查看jenkins配置存放目录 2.修改config.xml的useSecurity的true为flase 3.重启jenkins服务 4.进入jenkins,不输入密码直接就进入了jenkins ...
- 阿里云服务器ECS Ubuntu16.04 初次使用配置教程(图形界面安装)
原文链接:? 传送门 前一阵子购买了阿里云的云服务器ECS(学生优惠),折腾了一阵子后对有些东西不太满意,所以就重新初始化了磁盘,刚好要重新安装图形界面,于是就顺手写了这么一篇文章. 第一次登陆服务器 ...
- lua中的三目运算符
开头先说结论 1.简单版三目运算符(需要自我保证"b"不为"false") a and b or c 2.通用版三目运算符 (a and {b} or {c}) ...
- vue3知识点的自我总结
1. 我们对ref的错误理解 ref 经常去监听基本数据类型. 同时也可以去监听[数组][对象]都是可以的. ref是深度的监听.并不是大家说的那样不能去监听复杂的数据类型. 只是根据我们推荐ref去 ...