Codeforcesラウンド#582(DIV。3)-G。パスQueries-互いに素セット

Codeforcesラウンド#582(DIV。3)-G。パスQueries-互いに素セット


【問題の内容】

あなたの木を与え、どのように多くの単純なパスを尋ねる\((U、V)\) 満たす\(uは\)にする(V \)\超えないのこのパスに最大値を\(k個\) \(Q \)のクエリ。

【溶液】

互いに素セット

すべてのサイド・バイ・重量小から大、クエリ値に\(K_I \)は、小から大にもあります。各クエリの値のための\(K_I \) 右側以下\(K_I \)辺と一緒に組み合わせることによって確認しました。ユニコムブロックは組み合わせのために、各ブロックユニコム応答の寄与である(\ \ {FRACサイズ\タイムズ(-size。1)} {2} \) ユニコムブロックを直接加算することができるすべての貢献。だから、毎回2つのノード、2つのノードのマイナス、プラス組み合わせ貢献が可能な第1の貢献ユニコムブロックをマージします。


【コード】

/*
 * @Author: Simon 
 * @Date: 2019-09-07 10:00:30 
 * @Last Modified by: Simon
 * @Last Modified time: 2019-09-07 10:29:11
 */
#include<bits/stdc++.h>
using namespace std;
typedef int Int;
#define int long long
#define INF 0x3f3f3f3f
#define maxn 200005
struct node{
    int u,v,w;
    node(){}
    node(int u,int v,int w):u(u),v(v),w(w){}
    bool operator <(const node&a)const{
        return w<a.w;
    }
}g[maxn],q[maxn];
int Set[maxn],Rank[maxn];
void init(int n){ //初始化
    for(int i=0;i<=n;i++){
        Set[i]=i;Rank[i]=1;
    }
}
int cal(int x){ //计算联通块的贡献
    return x*(x-1)/2;
}
int Find(int u){ //并查集的查找根节点
    return Set[u]==u?u:Set[u]=Find(Set[u]);
}
int res=0;
int ans[maxn];
void merge(int u,int v){ //并查集的合并
    u=Find(u),v=Find(v);
    if(Rank[u]<Rank[v]) swap(u,v);
    res-=cal(Rank[u]),res-=cal(Rank[v]); //减去u,v所在联通块的贡献
    Set[v]=u;Rank[u]+=Rank[v]; //合并两个联通块
    res+=cal(Rank[u]); //再加上合并后的联通块的贡献
}
Int main(){
#ifndef ONLINE_JUDGE
    //freopen("input.in","r",stdin);
    //freopen("output.out","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int n,m;cin>>n>>m;init(n);
    for(int i=1;i<n;i++){
        cin>>g[i].u>>g[i].v>>g[i].w;
    }
    sort(g+1,g+n);
    for(int i=1;i<=m;i++){
        cin>>q[i].w;q[i].u=i;
    }
    sort(q+1,q+m+1);
    int pos=1;
    for(int i=1;i<=m;i++){
        while(pos<n&&g[pos].w<=q[i].w){
            merge(g[pos].u,g[pos].v);
            pos++;
        }
        ans[q[i].u]=res;
    }
    for(int i=1;i<=m;i++) cout<<ans[i]<<" \n"[i==m];
#ifndef ONLINE_JUDGE
    cout<<endl;system("pause");
#endif
    return 0;
}

おすすめ

転載: www.cnblogs.com/--Simon/p/11479662.html
おすすめ