2007 Benelux Algorithm Programming Contest (BAPC 2007) A

来源:互联网 发布:spss数据分析认证 编辑:程序博客网 时间:2024/05/22 04:44

        题意:给一棵带权树,输出所有点对间的平均距离。

        思路:在总距离中,一条边被计算了多少次取决于边的两端顶点数量的乘积,所以我们统计每条边两端分别有多少顶点。方法是,把树转化为有根树,然后统计每个顶点有多少孩子(包括孩子的孩子),那么边的其中一端顶点的数量就是它加上1。


#include <iostream>       #include <stdio.h>       #include <cmath>       #include <algorithm>       #include <iomanip>       #include <cstdlib>       #include <string>       #include <memory.h>       #include <vector>       #include <queue>       #include <stack>       #include <map>     #include <set>     #include <ctype.h>       #include <sstream>   #define INF 1000000000   #define ll long long   #define min3(a,b,c) min(a,min(b,c))   #define max3(a,b,c) max(a,max(b,c))   #define MAXN 1010        using namespace std;     struct edge{int u,v,w;edge(int a=0,int b=0,int c=0){u=a; v=b; w=c;}};edge edges[20010];vector<int> G[10010];vector<int> ch[10010];int p[10010];void dfs(int u,int fa){int d=G[u].size();for(int i=0;i<d;i++){int v=edges[ G[u][i] ].v;if(v!=fa){dfs(v,p[v]=u);ch[u].push_back(v);}}}int cnt[10010];int dfs2(int x){if(cnt[x])return cnt[x];int d=ch[x].size();cnt[x]+=d;for(int i=0;i<d;i++){cnt[x]+=dfs2(ch[x][i]);}return cnt[x];}int main(){int t;cin>>t;while(t--){memset(G,0,sizeof(G));memset(ch,0,sizeof(ch));memset(p,0,sizeof(p));memset(cnt,0,sizeof(cnt));ll n;cin>>n;for(int i=1;i<n;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);edges[i*2-1]=edge(u,v,w);G[u].push_back(i*2-1);edges[i*2]=edge(v,u,w);G[v].push_back(i*2);}dfs(0,-1);dfs2(0);ll ans=0;for(int i=1;i<n;i++){int son;if( p[ edges[i*2-1].u ]==edges[i*2-1].v ){son=edges[i*2-1].u;}else{son=edges[i*2-1].v;}ans+= (cnt[son]+1)*(n-cnt[son]-1)*edges[i*2-1].w;}ll t=n*(n-1)/2;printf("%.8lf\n",(ans+0.0)/t);}return 0;}


0 0
原创粉丝点击