标签:
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3449 Accepted Submission(s):
846
题意:求最小生成树,再求任意两点距离的期望。
最小生成树用kruscal。期望一开始不会求,看题解发现使用dfs:分别求每条边的贡献,一条边的贡献等于这条边的|左子树|*|右子树|*value。
代码中使用pair和vector
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; struct Path { int x,y; double value; } path[1000005]; typedef pair<int ,int> P; vector <P> edge[1000005]; bool cmp(Path a,Path b) { return a.value<b.value; } int father[100005],n,m;; int find(int x) { if(x!=father[x]) father[x]=find(father[x]); return father[x]; } void merge(int a,int b) { int x=find(a); int y=find(b); if(x!=y) father[x]=y; } long long sumv=0,sumd=0; void kruscal() { for(int i=1; i<=n; i++) father[i]=i; for(int i=0; i<=n; i++) edge[i].clear(); sort(path,path+m,cmp); for(int i=0; i<m; i++) { int x=path[i].x,y=path[i].y,value=path[i].value; if(find(path[i].x)!=find(path[i].y)) { sumv+=path[i].value; merge(path[i].x,path[i].y); edge[x].push_back(P(y,value)); edge[y].push_back(P(x,value)); } } } int dfs(int x,int last) { int cnt=0; for(int i=0;i<edge[x].size();i++) { int y=edge[x][i].first,value=edge[x][i].second; if(last!=y) { int now=dfs(y,x); cnt+=now; sumd+=1.0*now*(n-now)*value; } } return cnt+1; }
int main() { int t; scanf("%d",&t); while(t--) { sumv=0; sumd=0; scanf("%d%d",&n,&m); for(int i=0; i<m; i++) { scanf("%d%d%lf",&path[i].x,&path[i].y,&path[i].value); } kruscal(); dfs(1,-1); printf("%I64d %.2lf\n",sumv,sumd*2.0/(1.0*n)/(n-1.0)); } return 0; }
标签:
原文地址:http://www.cnblogs.com/jasonlixuetao/p/5702215.html