Codeforces Round #582 (Div. 3) G. Path Queries
https://codeforces.com/contest/1213/problem/G(图论)
思路:保证每次加入的边一定不会小于现存的图中的边,因为题目保证了一定为一棵树,所以每次加入的边必定属于不同的集合,计算下每个集合的个数,新加入的边一定会增加 sum[u] * sum[v] 所属不同集合的节点个数
]#include<bits/stdc++.h>
#define inf (0x3f3f3f3f)
using namespace std;
typedef long long i64;
const int maxn = 2e5 + 32;
struct Edge{
int from,to,w;
bool operator<(const struct Edge& e)
{
return w < e.w;
}
}edge[maxn];
int q[maxn],sum[maxn],p[maxn];
i64 cnt[maxn];
int find(int cur)
{
if(p[cur] != cur)
p[cur] = find(p[cur]);
return p[cur];
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0),cout.tie(0);
int n,m; cin>>n>>m;
for(int i=1;i<=n;++i)
p[i] = i,sum[i] = 1;
for(int i=1;i<=n-1;++i)
cin>>edge[i].from>>edge[i].to>>edge[i].w;
sort(edge+1,edge+n);
int maxquery = 0;
for(int i=1;i<=m;++i)
{
cin>>q[i];
maxquery = max(maxquery,q[i]);
}
for(int i=1;i<=n-1;++i)
{
int p1 = find(edge[i].from);
int p2 = find(edge[i].to);
cnt[edge[i].w] += (i64)sum[p1] * sum[p2];
p[p1] = p2;
sum[p2] += sum[p1]; sum[p1] = 0;
}
for(int i=1;i<=maxquery;++i)
cnt[i] += cnt[i-1];
for(int i=1;i<=m;++i)
cout<<cnt[q[i]]<<' ';
}
不怕万人阻挡,只怕自己投降。
posted on 2019-10-12 15:52 chengyulala 阅读(97) 评论(0) 收藏 举报
浙公网安备 33010602011771号