HDU 5441 2015长春站online1005(并查集)

这场比赛其实打的还是比较傻逼的,赛后做总结,感觉麟哥和真珍姐讲的还是蛮有道理的,现在如果再做专题的话没有什么意义了,这段时间准备多做点套题。

比赛的时候并不是我写的这题,赛后补了一下,写离线并查集的话,不断插满足条件的边,如果是u,v在两棵不同子树的话,那么这次查找的答案就是ans += 2*cnt[findset(u)]*cnt[findset(v)];这里应该比较好理解。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define LL long long
#define FOR(i,x,y)  for(int i = x;i < y;i ++)
#define IFOR(i,x,y) for(int i = x;i > y;i --)
#define N 20020
#define M 100010
#define Q 5005

using namespace std;

int n,m,q;

int fa[N];

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

struct Edge{
    int u,v;
    int val;
    bool operator < (const Edge& rhs) const{
        return val < rhs.val;
    }
}edge[M];

struct Commend{
    int x;
    int id;
    bool operator < (const Commend& rhs) const{
        return x < rhs.x;
    }
}cmd[Q];

int ans[Q];
int cnt[N];

int main()
{
    //freopen("test.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&m,&q);
        FOR(i,0,m){
            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].val);
        }
        sort(edge,edge+m);
        FOR(i,0,q){
            scanf("%d",&cmd[i].x);
            cmd[i].id = i;
        }
        sort(cmd,cmd+q);
        FOR(i,1,n+1)    {fa[i] = i;cnt[i] = 1;}
        int op = 0;
        int tem = 0;
        FOR(i,0,q){
            while(op < m && edge[op].val <= cmd[i].x){
                int u = findset(edge[op].u),v = findset(edge[op].v);
                op++;
                if(u == v)  continue;
                tem += 2*cnt[u]*cnt[v];
                fa[v] = u;
                cnt[u] += cnt[v];
            }
            ans[cmd[i].id] = tem;
        }
        FOR(i,0,q){
            printf("%d\n",ans[i]);
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值