Hidden Bipartite Graph

news/2024/10/6 19:57:37/文章来源:https://www.cnblogs.com/liyixin0514/p/18448466

Hidden Bipartite Graph

题意

交互题。有一个 \(n \le 600\) 的图,你可以询问至多 \(20000\) 次。每次问一个点集 \(S\),返回满足两个端点都在 \(S\) 中的边的个数。你需要判断这个图是不是二分图,如果是,则分别输出左部和右部的点,否则按顺序输出任意一个奇环。

思路

先判断二分图。一个十分巧妙的方法是,先找出一棵生成树,然后染色,然后再拓展判断是否是二分图。这样做是因为生成树是好找的(图保证连通),而且树是特别的二分图。

现在我们任意找出一棵生成树。我们发现判断一个点 \(x\) 和一个点集 \(S\) 有没有连边是容易的,只需要先问 \(S+x\),然后再问 \(S\),然后相减。

设已经连通的点集为 \(T\),剩余点集为 \(S\)。初始 \(T=\{1\},S=2 \sim n\)

找树边的时候我们逮住 \(T\) 的一个点 \(x\),然后二分的方式找出和它相连的所有点,并把这些点加入 \(T\),然后 \(x\) 的使命就结束了了,可以把它从 \(T\) 删除,因为它无法再用来更新边了。

这样每个点加入生成树最多要 \(2 \log n\) 次询问,一共 \(2n \log n\) 左右,大概 \(10800\)

然后我们就找到了一棵生成树。然后给这棵树黑白染色,就是奇数层染黑色,偶数层染白色。然后黑、白两个点集分别查询一下内部是否有边,如果没有,那么这两个点集就是二分图的左右部,否则不存在二分图。

如果不存在二分图,我们还需要找一个奇环。只要生成树上奇数层和奇数层或者偶数层和偶数层有连边,就行成了一个奇环。环包括书上路径和非树边的那一条边。因此我们对于每个奇数层的点(当然偶数层也同理可以),采用同样的方式二分所有奇数层的点(除去它自己),先判断一下有没有连边,如果有就找到一个和它有连边的点。一共大概 \(2n+2 \log n\) 次询问。完全足够。

code

#include<bits/stdc++.h>
//#define LOCAL
#define sf scanf
#define pf printf
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
using namespace std;
typedef long long ll;
const int N=1000;
int n;
vector<int> res;
int st[N],top;
int m;
int dep[N],fa[N];
vector<int> to[N];
int write(vector<int> &vec,int l,int r) {if(r-l+1<2) return 0;cout<<"? "<<r-l+1<<endl;rep(i,l,r) cout<<vec[i]<<' ';cout<<endl;cin>>m;return m;
}
int write(vector<int> &vec,int l,int r,int y) {if(r-l+1<=0) return 0;cout<<"? "<<r-l+1+1<<endl;rep(i,l,r) cout<<vec[i]<<' ';cout<<y<<endl;cin>>m;return m;
}
int write(int x,int y) {cout<<"? 2"<<endl;cout<<x<<' '<<y<<endl;cin>>m;return m;
}
vector<int> del;
void solve(int u,int l,int r) {if(l==r) {int m=write(u,res[l]);if(m) del.push_back(l),st[++top]=res[l],to[u].push_back(res[l]),to[res[l]].push_back(u);return;}int m=write(res,l,r,u)-write(res,l,r);if(!m) return;int mid=(l+r)>>1;solve(u,l,mid);solve(u,mid+1,r);
}
vector<int> lb,rb;
int col[N];
void dfs(int u) {if(col[u]==1) lb.push_back(u);else rb.push_back(u);for(int v:to[u]) {if(col[v]) continue;dep[v]=dep[u]+1;fa[v]=u;col[v]=col[u]==1?2:1;dfs(v);}
}
bool check() {if(lb.size()>=2) {cout<<"? "<<lb.size()<<endl;for(int u:lb) cout<<u<<' ';cout<<endl;cin>>m;if(m) return 0;}if(rb.size()>=2) {cout<<"? "<<rb.size()<<endl;for(int u:rb) cout<<u<<' ';cout<<endl;cin>>m;if(m) return 0;}return 1;
}
bool check(vector<int> &vec,int u) {return write(vec,0,vec.size()-1,u)-write(vec,0,vec.size()-1);
}
bool check(int u,vector<int> &vec,int l,int r) {return write(vec,l,r,u)-write(vec,l,r);
}
int find(int u,vector<int> &vec,int l,int r) {if(l==r) return vec[l];int mid=(l+r)>>1;if(check(u,vec,l,mid)) return find(u,vec,l,mid);else return find(u,vec,mid+1,r);
}
int main(){#ifdef LOCALfreopen("in.txt","r",stdin);
//	freopen("my.out","w",stdout);#endifcin>>n;rep(i,2,n) res.push_back(i);st[++top]=1;while(!res.empty()) {int u=st[top--];solve(u,0,(int)res.size()-1);vector<int> tmp;sort(del.begin(),del.end());int op=0;rep(i,0,(int)res.size()-1) {if(op<(int)del.size()&&i==del[op]) op++;else tmp.push_back(res[i]);}del.clear();res=tmp;}col[1]=1;dep[1]=1;dfs(1);if(check()) {sort(lb.begin(),lb.end());int k=unique(lb.begin(),lb.end())-lb.begin();cout<<"Y "<<k<<endl;for(int j=0;j<k;j++) cout<<lb[j]<<' ';cout<<endl;}else{rep(i,0,(int)lb.size()-1) {vector<int> tmp;rep(j,0,i-1) tmp.push_back(lb[j]);rep(j,i+1,(int)lb.size()-1) tmp.push_back(lb[j]);if(check(tmp,lb[i])) {int x=find(lb[i],tmp,0,tmp.size()-1);vector<int> lp,lp2;int y=lb[i];if(dep[x]<dep[y]) swap(x,y);while(dep[x]>dep[y]) {lp.push_back(x);x=fa[x];}while(x!=y) {lp.push_back(x),lp2.push_back(y);x=fa[x],y=fa[y];}lp.push_back(x);cout<<"N "<<lp.size()+lp2.size()<<endl;for(int u:lp) cout<<u<<' ';for(int k=lp2.size()-1;k>=0;k--) cout<<lp2[k]<<' ';cout<<endl;return 0;}}rep(i,0,(int)rb.size()-1) {vector<int> tmp;rep(j,0,i-1) tmp.push_back(rb[j]);rep(j,i+1,(int)rb.size()-1) tmp.push_back(rb[j]);if(check(tmp,rb[i])) {int x=find(rb[i],tmp,0,tmp.size()-1);vector<int> lp,lp2;int y=rb[i];if(dep[x]<dep[y]) swap(x,y);while(dep[x]>dep[y]) {lp.push_back(x);x=fa[x];}while(x!=y) {lp.push_back(x),lp2.push_back(y);x=fa[x],y=fa[y];}lp.push_back(x);cout<<"N "<<lp.size()+lp2.size()<<endl;for(int u:lp) cout<<u<<' ';for(int k=lp2.size()-1;k>=0;k--) cout<<lp2[k]<<' ';cout<<endl;return 0;}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/809176.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ide启动多个实例

ide启动多个实例 方法一: ide 2022.X及之后 Run=> Edit Configurations=> 选中项目=> “Build and run”栏=> Modify Options=> 选中“Allow multiple instances”然后就可以run多次项目了 但是要主要改端口 方法二: 先把项目打包,然后启动多个terminal,每个…

周鸿祎:用这10条打造你的完美的商业计划书(附详细讲解)

转载:周鸿祎:用这10条打造你的完美的商业计划书(附详细讲解)_产品 (sohu.com) 江湖上流传着一篇“360大佬周鸿祎版10页商业计划书PPT”,高屋建瓴的讲述了BP制作框架,很有价值。诚然,一个形式上外观精美,具有上有吸引力的BP让人赏心悦目,但更重要的还是有实实在在的内容…

DiLiGenT光度立体数据集

本文对DiLiGenT光度立体数据集进行了详细介绍。简介 ”DiLiGenT“ 光度立体数据集,全称为 calibrated Directional Lightings, objects of General reflectance, and ‘ground Truth’ shapes (normals),即使用标定过的定向光源,对一些具有常见反射率特性的物体进行光度立体…

Pool Kings All In One

Pool Kings All In One 泳池之王 Pool Kings - Mountain Paradise / 泳池之王 - 山间天堂 Utah waterfall MountainPool Kings All In One泳池之王demosPool Kings - Mountain Paradise / 泳池之王 - 山间天堂Utah waterfall Mountainhttps://vimeo.com/233842674 https://www.…

CHT

水电费是否收到fwe】今天探索一下CTH的电脑 PEPPA PIG放映室!tm的图怎么死了

visdom可视化工具

安装visdom可视化工具 pip install visdom -i 作者:太一吾鱼水 宣言:在此记录自己学习过程中的心得体会,同时积累经验,不断提高自己! 声明:博客写的比较乱,主要是自己看的。如果能对别人有帮助当然更好,不喜勿喷! 文章未经说明均属原创,学习笔记可…

测绘地理信息赋能新质生产力

在信息化与智能化浪潮的推动下,测绘地理信息作为连接现实世界与数字空间的桥梁,正逐步成为驱动经济社会发展的新质生产力。本文旨在深入探讨测绘地理信息如何通过技术创新与应用拓展,为各行各业赋能,塑造智慧社会的新面貌。一、测绘地理信息的转型之路随着卫星定位系统(如…

2024-2025-1 20241327 《计算机基础与程序设计》第2周学习总结

作业信息 |2024-2025-1-计算机基础与程序设计)| |-- |- |2024-2025-1计算机基础与程序设计第二周作业)| |快速浏览一遍教材计算机科学概论(第七版),课本每章提出至少一个自己不懂的或最想解决的问题并在期末回答这些问题 |作业正文|https://www.cnblogs.com/shr060414/p/18…

守护“金饭碗”:耕地保护,为经济社会发展筑牢根基

耕地,那片孕育着希望的田野,是我们共同的“金饭碗”。它不仅滋养着亿万生灵,更是我国经济社会发展的坚实后盾。那么,这“金饭碗”究竟蕴藏着怎样的力量,对我国经济社会发展起着怎样的作用呢?一、守护“金饭碗”,粮食安全有保障想象一下,如果我们的“金饭碗”不再丰盈,…

城市扩张与土地资源:压力之下寻平衡之道

在飞速发展的现代城市化进程中,城市扩张犹如一股不可阻挡的力量,既见证了人类文明的辉煌成就,也给土地资源带来了前所未有的压力与挑战。深入分析城市扩张对土地资源造成的影响,并探索可持续的解决方案,以期在城市发展的大潮中,找到与自然和谐共生的平衡点。 一、城市扩张…

实景三维赋能矿山安全风险监测预警

随着科技的不断进步,实景三维技术在矿山安全风险监测预警中的应用越来越广泛,它为矿山安全管理带来了革命性的变革。一、矿山安全现状矿山作为国家重要的能源和原材料基地,其安全生产直接关系到国民经济的发展和社会的稳定。然而,矿山作业环境复杂,地质条件多变,加之人为…

【笔记】SSTI学习

学习记录什么是SSTI的东西 所以什么是SSTI啊? 我不到啊!【笔记】SSTI学习 原文章:尝试黑客攻击 |SSTI (tryhackme.com) 介绍 服务器端模板注入(SSTI)是一种web漏洞攻击,它利用模板引擎的不安全特性实现。 什么是模板引擎? 模板引擎允许您创建可以在应用程序中重复使用的静…