G. Vlad and the Mountains
题意:给你每个点的高度,从a到b需要消耗h[b]-h[a]的体力值(所以说下坡时体力值可以增加),询问一开始你有e的体力值,问是否可以从u->v点
分析:
1.a->b最终消耗的体力值一定为h[b]-h[a],如果一开始的体力值都达不到肯定无法过
2.如果期间高度大于h[a]+c,那么也是过不了的
方法:
1.我们对加边取最高点进行排序,原因:高度越小越可能爬到
2.对询问进行离线处理,并对其以h[a]+e进行排序,原因:如果加边的权值小于询问的最大值,那么两点在此高度下可以到达,将其加入并查集中
3.因为询问能到达的最大高度是递增的,所以后续不影响,如果询问的两点在并查集中,说明可以到达,反之不行
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int h[N];
struct node{
int u,v,w,id;
}a[N],qry[N];
bool cmp(node a,node b){
return a.w<b.w;
}
int f[N];
int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
}
int ans[N];
void solve(){
int n,m;
cin>>n>>m;
memset(ans,0,sizeof ans);
for(int i=1;i<=n;i++) f[i]=i;//并查集
for(int i=1;i<=n;i++) cin>>h[i];
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
int w=max(h[u],h[v]);//记录最高值
a[i].u=u;a[i].v=v;a[i].w=w;
}
sort(a+1,a+1+m,cmp);
int q;
cin>>q;
for(int i=1;i<=q;i++){
int a,b,c;
cin>>a>>b>>c;
qry[i].u=a;
qry[i].v=b;
qry[i].w=h[a]+c;//h[a]+c可以到达的最高高度
qry[i].id=i;//离线查询
}
sort(qry+1,qry+1+q,cmp);
int p=1;
for(int i=1;i<=q;i++){
while(p<=m&&qry[i].w>=a[p].w){//加边,如果高度小于能到达的查询高度,说明可以
int x=find(a[p].v);
int y=find(a[p].u);
if(x!=y){
f[x]=y;
}
p++;
}
if(find(qry[i].u)==find(qry[i].v)) ans[qry[i].id]=1;//如果两者在并查集里面,说明两者连同
}
for(int i=1;i<=q;i++){
if(ans[i]) cout<<"YES\n";
else cout<<"NO\n";
}
cout<<'\n';
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】