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;
}

posted @ 2025-11-23 22:55  NDAKJin  阅读(3)  评论(0)    收藏  举报