hdu 4750——Count The Pairs

来源:互联网 发布:内蒙古出版社 知乎 编辑:程序博客网 时间:2024/06/06 10:03

题意:南京理工大学有很多景点。两个景点组成一对。两个景点的价值用这种方式计算:设两个景点之间一条路径中最长的一条路的距离是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;}
0 0
原创粉丝点击