hdu 4750——Count The Pairs

题意:南京理工大学有很多景点。两个景点组成一对。两个景点的价值用这种方式计算:设两个景点之间一条路径中最长的一条路的距离是s,这两个景点的价值f就是所有路径中s的最小值。游客想要找价值大于等于t的景点对有多少个。
思路:将边按照权值从小到大排序。依次遍历每条边。因为每次加入的边是当前遍历过的边中最大的,若这条边连接的两个节点不在同一个集合中,那么这两个集合之间点对的价值就是这条边的权值。
错误:合并的时候把两个集合大小计算写错了。。不是一次犯这种低级错误了。
代码如下:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<map>
#include<set>
#include<list>
#include<stack>
#include<algorithm>
#include<queue>
#include<vector>
#include<time.h>
#include<iomanip>
#include<assert.h>
using namespace std;

typedef long long ll;

struct Edge
{
    int u,v,w;
    bool operator < (const Edge &a) const {
        return w < a.w;
    }
    bool operator == (const Edge &a) const {
        return w == a.w;
    }
    bool operator > (const Edge &a) const {
        return w>a.w;
    }
    Edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){}
}edge[500005];

int fa[10005];
int cnt[10005];

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

void merge(int x,int y)
{
    int a = find(x);int b = find(y);
    fa[a] = b;
    cnt[b] += cnt[a];
    cnt[a] += cnt[b];
}

int n,m;
ll ans[500005];

int bisearch(int x){
    int l = 0;int r = m-1;
    while(l<=r){
        int mid = (l+r);mid>>=1;
        if(edge[mid].w == x){
            return mid;
        }
        if(edge[mid].w<x){
            l = mid+1;
        } else r = mid-1;
    }
    return l;
}

int main()
{
//    freopen("data.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i = 0 ; i < m; ++ i ){
            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
        }
        sort(edge,edge+m);
        for(int i = 0; i < n;++i){
            fa[i] = i;
            cnt[i] = 1;
        }
        memset(ans,0,sizeof(ans));
        for(int i = 0 ; i < m; ++i){
            int u = edge[i].u;
            int v = edge[i].v;
            int a = find(u);int b = find(v);
            if(a == b)continue;
            ans[i] = (ll)cnt[a]*(ll)cnt[b]*2;
            merge(a,b);
        }
        for(int i = m-2;i>=0;--i){
            ans[i] += ans[i+1];
        }
        int p;
        scanf("%d",&p);
        while(p--){
            int t;
            scanf("%d",&t);
            int c = bisearch(t);
            printf("%I64d\n",ans[c]);
        }
    }
    return 0;
}
发布了267 篇原创文章 · 获赞 12 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u010734277/article/details/47321515