zoukankan      html  css  js  c++  java
  • hdu 3938 并查集

    思路:这题的出题人是不是语文不行啊,题目意思说不清楚。

    知道是求存在路径的点对数后,用并查集每次记录集合中点的数目,很容易就解决了。

    #include<set>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pb push_back
    #define mp make_pair
    #define Maxn 200100
    #define Maxm 800002
    #define LL __int64
    #define Abs(x) ((x)>0?(x):(-x))
    #define lson(x) (x<<1)
    #define rson(x) (x<<1|1)
    #define inf 1000000000
    #define lowbit(x) (x&(-x))
    #define Mod 1000000007
    using namespace std;
    int fa[Maxn],cnt;
    LL num[Maxn],ans[Maxn];
    struct Edge{
        int u,v,val;
        int operator< (const Edge &temp) const
        {
            return val<temp.val;
        }
    }p[Maxm];
    struct Query{
        int val,id;
        int operator< (const Query &temp) const{
            return val<temp.val;
        }
    }q[Maxn];
    void init()
    {
        for(int i=0;i<Maxn;i++){
            fa[i]=i;
            ans[i]=0;
            num[i]=1;
        }
    }
    int find(int x)
    {
        if(x!=fa[x])
            fa[x]=find(fa[x]);
        return fa[x];
    }
    LL merg(int a,int b)
    {
        int x=find(a);
        int y=find(b);
        if(x==y) return 0;
        LL ans=num[x]*num[y];
        num[x]+=num[y];
        fa[y]=x;
        ++cnt;
        return ans;
    }
    int main()
    {
        int n,m,t,i,j,u,v;
        while(scanf("%d%d%d",&n,&m,&t)!=EOF){
            init();
            for(i=1;i<=m;i++){
                scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].val);
            }
            for(i=1;i<=t;i++)
                scanf("%d",&q[i].val),q[i].id=i;
            sort(p+1,p+1+m);
            sort(q+1,q+1+t);
            p[m+1].val=inf;
            p[m+1].u=1,p[m+1].v=1;
            j=1;
            LL sum=0;
            cnt=0;
            int pos=1;
            for(i=1;i<=m+1;i++){
                while(j<=t&&q[j].val<p[i].val){
                    ans[q[j].id]=sum;
                    j++;
                }
                sum+=merg(p[i].u,p[i].v);
            }
            while(j<=t&&q[j].val<p[i].val)
            {
                ans[q[j].id]=sum;
                    j++;
            }
            for(i=1;i<=t;i++){
                printf("%I64d
    ",ans[i]);
            }
        }
        return 0;
    }
  • 相关阅读:
    团队项目成员和题目
    最大联通子数组
    站立会议5
    关于jsp之间href传参(中文)乱码问题
    站立会议4
    典型用户和用户场景描述
    站立会议3
    站立会议2
    站立会议1
    第七周学习进度情况
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3303849.html
Copyright © 2011-2022 走看看