HDU 5723(mst+dfs)

来源:互联网 发布:郑元畅为什么不红 知乎 编辑:程序博客网 时间:2024/05/18 02:34

题目链接
跑一遍mst,同时构造出树,再在树上跑一遍dfs,就可以计算出任意2点之间的距离了

#include<bits/stdc++.h>using namespace std;#define cl(a,b) memset(a,b,sizeof(a))#define LL long long#define pb push_backconst int maxn = 1e5+200;const int inf  = 1 << 23;int n,m;struct Edge{    int x,y,w;    bool operator<(const Edge a) const{        return w<a.w;    }}G[maxn*10];int f[maxn];void init(int n){    for(int i=0;i<=n;i++){        f[i]=i;    }}int find(int x){    if(f[x]==x)return x;    return f[x]=find(f[x]);}void merge(int x,int y){    x=find(x);y=find(y);    if(x==y)return ;    f[x]=y;}bool same(int x,int y){    return find(x)==find(y);}struct Edge2{    int to,w;};vector<Edge2> G2[maxn];LL sum[maxn];double ret ;void dfs(int x,int fa){    sum[x]=1;    for(int i=0;i<G2[x].size();i++){        int y = G2[x][i].to;        int w = G2[x][i].w;        if(y==fa)continue;        dfs(y,x);        sum[x]+=sum[y];        ret+=1.0*sum[y]*(n-sum[y])*w;    }}int main(){    int T;scanf("%d",&T);    while(T--){        for(int i=0;i<maxn;i++){            G2[i].clear();            sum[i]=0;        }        scanf("%d%d",&n,&m);        init(n);        for(int i=0;i<m;i++){            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            G[i]=(Edge){x,y,z};        }        sort(G,G+m);        LL ans=0;        for(int i=0;i<m;i++){            if(same(G[i].x,G[i].y))continue;            merge(G[i].x,G[i].y);            ans+=G[i].w;            G2[G[i].x].pb((Edge2){G[i].y,G[i].w});            G2[G[i].y].pb((Edge2){G[i].x,G[i].w});        }        ret = 0;        dfs(1,-1);        printf("%lld %.2lf\n",ans,ret/(n-1)/n*2);    }    return 0;}
0 0
原创粉丝点击