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 (并查集+整体二分)的更多相关文章

  1. [agc002D]Stamp Rally-[并查集+整体二分]

    Description 题目大意:给你一个n个点m个条边构成的简单无向连通图,有Q组询问,每次询问从两个点x,y走出两条路径,使这两条路径覆盖z个点,求得一种方案使得路径上经过的边的最大编号最小.n, ...

  2. [AGC002D] Stamp Rally

    确实有想到重构树,不过没有继续下去的思路. 可能是对重构树的性质不太懂. 这种题目我们可以二分答案,考虑怎么\(check\)呢,整体二分+并查集,建出重构树,找去第一个小于这个数的方点,查询他的子树 ...

  3. [AGC002D] Stamp Rally 整体二分+并查集

    Description 给你一个n个点m个条边构成的简单无向连通图,有Q组询问,每次询问从两个点x,y走出两条路径,使这两条路径覆盖z个点,求得一种方案使得路径上经过的变的最大编号最小. Input ...

  4. 【做题】agc002D - Stamp Rally——整体二分的技巧

    题意:给出一个无向连通图,有\(n\)个顶点,\(m\)条边.有\(q\)次询问,每次给出\(x,y,z\),最小化从\(x\)和\(y\)开始,总计访问\(z\)个顶点(一个顶点只计算一次),经过的 ...

  5. NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...

  6. POJ3228 并查集或二分最大流枚举答案

    忘记写题意了.这题题意:给出每个地点的金矿与金库的数量,再给出边的长度.求取最大可通过边长的最小权值使每个金矿都能运输到金库里. 这题和之前做的两道二分枚举最大流答案的问法很相识,但是这里用最大流速度 ...

  7. 【2018百度之星初赛 B】1001并查集 1004二分 1006不等式

    1001 degree 题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6380 并查集向图中加点,分别记录与初始度数最多的点 直接相连的点数.独立的点数 ...

  8. HDU-3081-Marriage Match II 二分图匹配+并查集 OR 二分+最大流

    二分+最大流: 1 //题目大意:有编号为1~n的女生和1~n的男生配对 2 // 3 //首先输入m组,a,b表示编号为a的女生没有和编号为b的男生吵过架 4 // 5 //然后输入f组,c,d表示 ...

  9. NOIP 2010 关押罪犯 并查集 二分+二分图染色

    题目描述: S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值" ...

随机推荐

  1. 关于小程序 scroll-view中设置scroll-top无效 和小说图书阅读进度条小案例

    在最近的项目有做到关于小说阅读的进度条功能,其中用到scroll-view和slider组件,发现scroll-view中的scroll-top在设置值后无效,出现这种情况大概是以下几种问题: 1.s ...

  2. Express中间件简单的实现原理

    上一篇理解Express的使用之后, 再总结一篇Express中间件的简单实现原理. 我们知道Express中间件就是一个个的函数, 那么怎么让这些函数有序的执行呢? 那就需要我们调用 next 函数 ...

  3. ThinkPHP函数I代码优化

    ThinkPHP/Common/common.php 文件 I函数,主要用来获取一些gpc请求的变量的,函数有一部分代码是过滤变量的,每次都运行一次,其实是没有必要的. 如果你每次都像这样的方式调用的 ...

  4. C语言实现判断分数等级

    从屏幕上输入一个学生的成绩(0-100),对学生成绩进行评定: <=60为"E" 60~69为"D" 70~79为"C" 80~89为 ...

  5. pandas知识点(处理缺失数据)

    pandas使用浮点值NaN表示浮点和非浮点数组中的缺失数据: In [14]: string_data = Series(['aardvark','artichoke',np.nan,'avocad ...

  6. 动态规划:最长上升子序列之基础(经典算法 n^2)

    解题心得: 1.注意动态转移方程式,d[j]+1>d[i]>?d[i]=d[j]+1:d[i] 2.动态规划的基本思想:将大的问题化为小的,再逐步扩大得到答案,但是小问题的基本性质要和大的 ...

  7. [GDOI2016][树链剖分+主席树]疯狂动物城

    题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...

  8. 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”) 让 ...

  9. 利用python多线程模块实现模拟接口并发

    import requestsimport jsonimport threadingimport timeimport uuid class postrequests(): def __init__( ...

  10. ThinkPHP5 连接 PostgreSQL

    $request = Db::connect( [ 'type' => 'pgsql', 'hostname' => '127.0.0.1', 'database' => 'keyw ...