hdu7132city(离线处理+并查集)

q次询问,每次求出边长大于k构成图中能两两互达的点的对数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define LL long long
const int N=2e5+7;

int fa[N],sz[N];

struct E
{
    int x,y,z;
}e[N];

struct Q
{
    int id,k;
    LL ans;
}q[N];

bool  cmp_z(E a,E b)
{
    return a.z>b.z;
}

bool cmp_k(Q a,Q b)
{
    return a.k>b.k;
}

bool cmp_id(Q a,Q b)
{
    return a.id<b.id;
}

int f(int x)
{
    return fa[x]==x?x:fa[x]=f(fa[x]);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m,p;
        scanf("%d%d%d",&n,&m,&p);
        for(int i=1;i<=n;i++)
        {
            fa[i]=i;
            sz[i]=1;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
        }
        sort(e+1,e+m+1,cmp_z);
        for(int i=1;i<=p;i++)
        {
            scanf("%d",&q[i].k);
            q[i].id=i;
        }
        sort(q+1,q+p+1,cmp_k);
        LL ans=0;
        int h=1;
        for(int i=1;i<=p;i++)
        {
            int k=q[i].k;
            while(e[h].z>=k&&h<=m)
            {
                int x=e[h].x,y=e[h].y;
                int fx=f(x),fy=f(y);
                if(fx==fy)
                {
                    h++;
                    continue;
                }
              //  ans=ans-1ll*sz[fx]*(sz[fx]-1)/2;
              //  ans=ans-1ll*sz[fy]*(sz[fy]-1)/2;
             //   ans=ans+1ll*(sz[fx]+sz[fy])*(sz[fx]+sz[fy]-1)/2;
                ans=ans+1ll*sz[fx]*sz[fy];
                fa[fx]=fy;
                sz[fy]+=sz[fx];
                h++;
            }
            q[i].ans=ans;
        }
        sort(q+1,q+p+1,cmp_id);
        for(int i=1;i<=p;i++)
        {
            cout<<q[i].ans<<endl;
        }
    }
    return 0;
}
上一篇:【DOS 6.0模块】handicap.asm


下一篇:leetcode-华为专题-1353. 最多可以参加的会议数目