#1,7 ac,20分求助
查看原帖
#1,7 ac,20分求助
667250
Xiphi楼主2023/11/8 20:29
/*
给出一棵n个点的树及每条边的边权,定义任意两个点的熟悉度为连接这两个点的路径上边权的最小值。
再给出Q个询问,每次询问给出数对(ki,vi),要求计算出有多少个节点与节点vi的熟悉度大于等于ki。
*/
#include<bits/stdc++.h>
using namespace std;
int n,q,cnt=0,size[100005];
pair<int,int> k[100005];
int fa[100005];
struct node {
	int a,b,c;
}e[100005];
int ans[100005];
map<pair<int,int>,int> pos;
void build() {
	for(int i=1;i<=n;++i) fa[i]=i,size[i]=1;
}
int find(int x) {
	if(fa[x]==x) return x;
	else {
		return fa[x]=find(fa[x]);
	}
}
void merge(int x,int y) {
	int fax=find(x),fay=find(y);
	if(fax!=fay) {
		fa[fay]=fax;
		size[fax]+=size[fay];
	}
}
bool cmp(pair<int,int> x,pair<int,int> y){
	return x.first>y.first;
}
bool cmpp(node x,node y) {
	return x.c>y.c;
} 
int main(){
	cin>>n>>q;
	build();
	for(int i=1;i<n;++i) {
		cin>>e[i].a>>e[i].b>>e[i].c; 
	} 
	for(int i=1;i<=q;++i) {
		cin>>k[i].first>>k[i].second;
		pos[k[i]]=i;
	}
	sort(e+1,e+n,cmpp);
	sort(k+1,k+q+1,cmp);
	int it=1;
	for(int i=1;i<=q;++i) {
		int lim=k[i].first,v=k[i].second;
		while(it<=n&&e[it].c>=lim){
			merge(find(e[it].a),find(e[it].b));
			it++;
		}
		ans[pos[k[i]]]=size[find(v)]-1;
	} 
	for(int i=1;i<=q;++i) cout<<ans[i]<<'\n';
	return 0;
}
2023/11/8 20:29
加载中...