[AGC002D] Stamp Rally (并查集+整体二分)
Description
给你一个n个点m个条边构成的简单无向连通图,有Q组询问,每次询问从两个点x,y走出两条路径,使这两条路径覆盖z个点,求得一种方案使得路径上经过的变的最大编号最小。
Input
第一行两个整数n,m,如题目所述
接下来m行,每行两个整数x,y描述一条边
接下来一个整数Q,如题目所述
接下来Q行,每行三个整数x,y,z,如题目描述
Output
Q行,每行一个正整数,如题目描述
题解:
先想一想,可以用并查集解决,但 \(n^2\) 太慢了,于是就想到了整体二分。
我先是用了一个普通的并查集,结果发现每次都要初始化一遍,T 飞了。
后来想着可以支持删除,就不能路径压缩了(还是T飞),我了解到了一个黑科技,按秩合并。
我们合并两棵树的时候,我们把树高小的挂在树高大的下面,这样就能把树高控制在log级别。
然后我们加边的时候,用栈记录合并的两个节点,分完之后,再从栈中一个个地取出来恢复原样就好了。
到最后一个点的时候我们再把这条边连上,成功AC。
对了,我之前加了这个剪枝:
if(x<y)return;
就是说如果区间里没有数就不往下了,但这会导致有些边没有连,就WA了。
CODE:
#include<iostream>
#include<stack>
#include<cstdio>
using namespace std;
int n,m,q,ans[100005];
int siz[100005],fa[100005];
struct Edge{
int x,y;
}e[100005];
struct Question{
int x,y,z,id;
}Q[100005],tmp[100005];
stack<Edge> s;
int find(int x){
if(x==fa[x])return x;
return find(fa[x]);
}
void solve(int l,int r,int x,int y){
if(l==r){
for(int i=x;i<=y;i++)ans[Q[i].id]=l;
int fx=find(e[l].x),fy=find(e[l].y);
if(siz[fx]>siz[fy])swap(fx,fy);
if(fx!=fy)fa[fx]=fy,siz[fy]+=siz[fx];
return;
}
int mid=l+r>>1;
for(int i=l;i<=mid;i++){
int fx=find(e[i].x),fy=find(e[i].y);
if(siz[fx]>siz[fy])swap(fx,fy);
if(fx!=fy){
fa[fx]=fy,siz[fy]+=siz[fx];
s.push((Edge){fx,fy});
}
}
int tot1=x-1,tot2=0;
for(int i=x,size;i<=y;i++){
int fx=find(Q[i].x),fy=find(Q[i].y);
if(fx==fy)size=siz[fx];
else size=siz[fx]+siz[fy];
if(size>=Q[i].z)Q[++tot1]=Q[i];
else tmp[++tot2]=Q[i];
}
for(int i=1;i<=tot2;i++)Q[tot1+i]=tmp[i];
while(!s.empty()){
Edge e=s.top();s.pop();
fa[e.x]=e.x,siz[e.y]-=siz[e.x];
}
solve(l,mid,x,tot1);
solve(mid+1,r,tot1+1,y);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&e[i].x,&e[i].y);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++)siz[i]=1;
scanf("%d",&q);
for(int i=1;i<=q;i++){
scanf("%d%d%d",&Q[i].x,&Q[i].y,&Q[i].z);
Q[i].id=i;
}
solve(1,m,1,q);
for(int i=1;i<=q;i++)
printf("%d\n",ans[i]);
}
[AGC002D] Stamp Rally (并查集+整体二分)的更多相关文章
- [agc002D]Stamp Rally-[并查集+整体二分]
Description 题目大意:给你一个n个点m个条边构成的简单无向连通图,有Q组询问,每次询问从两个点x,y走出两条路径,使这两条路径覆盖z个点,求得一种方案使得路径上经过的边的最大编号最小.n, ...
- [AGC002D] Stamp Rally
确实有想到重构树,不过没有继续下去的思路. 可能是对重构树的性质不太懂. 这种题目我们可以二分答案,考虑怎么\(check\)呢,整体二分+并查集,建出重构树,找去第一个小于这个数的方点,查询他的子树 ...
- [AGC002D] Stamp Rally 整体二分+并查集
Description 给你一个n个点m个条边构成的简单无向连通图,有Q组询问,每次询问从两个点x,y走出两条路径,使这两条路径覆盖z个点,求得一种方案使得路径上经过的变的最大编号最小. Input ...
- 【做题】agc002D - Stamp Rally——整体二分的技巧
题意:给出一个无向连通图,有\(n\)个顶点,\(m\)条边.有\(q\)次询问,每次给出\(x,y,z\),最小化从\(x\)和\(y\)开始,总计访问\(z\)个顶点(一个顶点只计算一次),经过的 ...
- NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...
- POJ3228 并查集或二分最大流枚举答案
忘记写题意了.这题题意:给出每个地点的金矿与金库的数量,再给出边的长度.求取最大可通过边长的最小权值使每个金矿都能运输到金库里. 这题和之前做的两道二分枚举最大流答案的问法很相识,但是这里用最大流速度 ...
- 【2018百度之星初赛 B】1001并查集 1004二分 1006不等式
1001 degree 题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6380 并查集向图中加点,分别记录与初始度数最多的点 直接相连的点数.独立的点数 ...
- HDU-3081-Marriage Match II 二分图匹配+并查集 OR 二分+最大流
二分+最大流: 1 //题目大意:有编号为1~n的女生和1~n的男生配对 2 // 3 //首先输入m组,a,b表示编号为a的女生没有和编号为b的男生吵过架 4 // 5 //然后输入f组,c,d表示 ...
- NOIP 2010 关押罪犯 并查集 二分+二分图染色
题目描述: S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值" ...
随机推荐
- 关于小程序 scroll-view中设置scroll-top无效 和小说图书阅读进度条小案例
在最近的项目有做到关于小说阅读的进度条功能,其中用到scroll-view和slider组件,发现scroll-view中的scroll-top在设置值后无效,出现这种情况大概是以下几种问题: 1.s ...
- Express中间件简单的实现原理
上一篇理解Express的使用之后, 再总结一篇Express中间件的简单实现原理. 我们知道Express中间件就是一个个的函数, 那么怎么让这些函数有序的执行呢? 那就需要我们调用 next 函数 ...
- ThinkPHP函数I代码优化
ThinkPHP/Common/common.php 文件 I函数,主要用来获取一些gpc请求的变量的,函数有一部分代码是过滤变量的,每次都运行一次,其实是没有必要的. 如果你每次都像这样的方式调用的 ...
- C语言实现判断分数等级
从屏幕上输入一个学生的成绩(0-100),对学生成绩进行评定: <=60为"E" 60~69为"D" 70~79为"C" 80~89为 ...
- pandas知识点(处理缺失数据)
pandas使用浮点值NaN表示浮点和非浮点数组中的缺失数据: In [14]: string_data = Series(['aardvark','artichoke',np.nan,'avocad ...
- 动态规划:最长上升子序列之基础(经典算法 n^2)
解题心得: 1.注意动态转移方程式,d[j]+1>d[i]>?d[i]=d[j]+1:d[i] 2.动态规划的基本思想:将大的问题化为小的,再逐步扩大得到答案,但是小问题的基本性质要和大的 ...
- [GDOI2016][树链剖分+主席树]疯狂动物城
题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 19: ordinal not in range(128)
解决方案: 1: 在网上找到的解决方案是: 在调用import matplotlib.pyplot as plt前 import sys sys.setdefaultencoding(“gbk”) 让 ...
- 利用python多线程模块实现模拟接口并发
import requestsimport jsonimport threadingimport timeimport uuid class postrequests(): def __init__( ...
- ThinkPHP5 连接 PostgreSQL
$request = Db::connect( [ 'type' => 'pgsql', 'hostname' => '127.0.0.1', 'database' => 'keyw ...