hdu 4750 Count The Pairs 并查集+递推(2013 ACM/ICPC Asia Regional Nanjing Online 1003)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=1e4+10;
const int maxm=5e5+10;
struct node{
    int a,b,c;
}e[maxm];
int f[maxn],n,m,ans[maxm],g[maxn],q[maxm];
int cmp(node x,node y)
{
    return x.c<y.c;
}
void init()
{
    int i,j,k;
    for(i=0;i<=n;i++){f[i]=i;g[i]=1;}
}
int find(int x)
{
    if(f[x]!=x)f[x]=find(f[x]);
    return f[x];
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int i,j,k,a,b,c,aa,bb,p,t,tt;
        init();
        for(i=1;i<=m;i++)
            scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c); 
        sort(e,e+m,cmp);
        ans[0]=0;
        q[m]=2e9;
        //ans[i]表示两点价值小于等于e[i].c的点对数。 
        for(i=1;i<=m;i++)
        {
            q[i-1]=e[i].c;
            aa=find(e[i].a);
            bb=find(e[i].b);
            if(aa==bb){ans[i]=ans[i-1];}
            else
            {
                ans[i]=ans[i-1]-g[aa]*(g[aa]-1)-g[bb]*(g[bb]-1)+(g[aa]+g[bb]-1)*(g[aa]+g[bb]);
                g[aa]+=g[bb];
                f[bb]=aa;
            }
        }
        ans[0]=n*(n-1);
        for(i=1;i<=m;i++)
        {
            ans[i]=n*(n-1)-ans[i];
        }
        scanf("%d",&p);
        while(p--)
        {
            scanf("%d",&t);
            tt=lower_bound(q,q+m,t)-q;
            printf("%d\n",ans[tt]);
        }
    }
    return 0;
}
/*
	题意:给定一个带有权值的图。两点的价值就是所有连接两点的路径的最小路径值。
路径值表示一个一条路径上的最大权值。输入一个t,问又多少对点价值大于等于t
	方法:由于权值都不同,我们可以从小到大枚举权值c。判断权值为c的两点a,b
是否在同一个并查集内。若不是则合并两个点集。则点集中任何两个点的价值都小于等于c。 
*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值