CF1851G-Vlad and the Mountains
CF1851G-Vlad and the Mountains
题目大意
一张无向图上有 \(n\) 个结点,每个节点有一个高度 \(h_i\) 。从结点 \(i\) 到 结点 \(j\) 的能量花费是 \(h_j-h_i\) 。如果途中能量降到零以下,则无法从 \(i\) 走到 \(j\) 。
一共有 \(q\) 次询问,能否初始拥有 \(e\) 点能量的情况下,从 \(a\) 结点走到 \(b\) 结点。
\(Hint\)
不难发现,题目的约束条件是,\(a\) 到 \(b\) 是否存在一条路径上所有点高度都不超过 \(e+h_a\) 的路径。
题解
开始先设立一张空图,按照点的高度 \(h_i\) 和 查询的高度限制 \(h_a+e\) 升序排序所有点和查询。
· 如果 \(pop\) 出了点,那么就并查集连接这个点与其所有高度小于等于该点的结点。
· 如果 \(pop\) 出了查询,那么直接查询当前 \(a\) 和 \(b\) 是否连通,连通则满足条件,不连通则不满足条件。
#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define umap unordered_map
#define endl '\n'
using namespace std;
using i128 = __int128;
const int mod =1e9+7;
template <typename T>void read(T&x){
x=0;int f = 1;
char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
x*=f;
}
template <typename T>void print(T x) {
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
#define int long long
class UnionFind {
public:
vector<int> parent;
UnionFind(int n){
parent.resize(n);
for (int i = 0; i < n; ++i) {
parent[i] = i;
}
}
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
void join(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
parent[rootX]=rootY;
}
}
};
const int N=500005;
const int M=2000005;
vector<int> G[200005];
inline void solve()
{
int n,m;
cin>>n>>m;
vector<int> h(n+1),vis(n+1);
UnionFind un(n+1);
priority_queue<pair<int,int> ,vector<pair<int,int>> ,greater<pair<int,int>>> nn;
priority_queue<tuple<int,int,int,int> ,vector<tuple<int,int,int,int>> ,greater<tuple<int,int,int,int>>> mm;
for(int i=1;i<=n;i++)
{
cin>>h[i];
G[i].clear();
nn.push({h[i],i});
}
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
int q;
cin>>q;
vector<int> ans(q+1);
for(int i=1;i<=q;i++)
{
int u,v,e;
cin>>u>>v>>e;
mm.push({e+h[u],u,v,i});
}
while(!nn.empty())
{
auto [H,i]=nn.top();
nn.pop();
while(!mm.empty())
{
auto [h,u,v,j]=mm.top();
if(h>=H) break;
if(un.find(u)==un.find(v))
{
ans[j]=1;
}
else
{
ans[j]=0;
}
mm.pop();
}
vis[i]=1;
for(auto v:G[i])
{
if(vis[v])
{
un.join(i,v);
}
}
}
while(!mm.empty())
{
auto [h,u,v,j]=mm.top();
if(un.find(u)==un.find(v))
{
ans[j]=1;
}
else
{
ans[j]=0;
}
mm.pop();
}
for(int i=1;i<=q;i++)
{
if(ans[i]) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
signed main()
{
ios;
int T=1;
cin>>T;
for(;T--;) solve();
return 0;
}

浙公网安备 33010602011771号