标签:最小 clear roo names amp 期望 ems 算法 生成树
题意要求跑最小生成树,然后求出任意两点距离的期望。
做法是用Kruskal算法并用前向星存最小生成树,然后用dfs得出期望。
代码
#include<bits/stdc++.h> #include<vector> using namespace std; #define ll long long int struct Edge{ int x; int y; int wei; }num[1010000]; struct Node { int to; int val; Node(int _to, int _val) :to(_to), val(_val) {} }; int vis[101000]; int sum[101000]; ll res; int n,m,k; vector<Node>vet[101000]; int init(int n) { for(int i=1;i<=n;i++) { vis[i]=i; } } int finds(int x) { if(x!=vis[x]) { vis[x]=finds(vis[x]); } return vis[x]; } int cmp(Edge a,Edge b) { return a.wei<b.wei; } void Dfs(int root, int father) { sum[root] = 1; for(int i = 0; i < vet[root].size(); i++) { int son = vet[root][i].to; int val = vet[root][i].val; if(son == father) continue; Dfs(son, root); sum[root] += sum[son]; res += (ll)(sum[son]) * (ll)(n - sum[son]) * val; } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d %d",&n,&m); long long int cnt=0; for(int i=1;i<=m;i++) { scanf("%d %d %d",&num[i].x,&num[i].y,&num[i].wei); } for(int i = 1; i <= n; i++) vet[i].clear(); sort(num,num+m,cmp); init(n); for(int i=1;i<=m;i++) { int u=num[i].x; int v=num[i].y; int fu=finds(u); int fv=finds(v); if(fu!=fv) { cnt+=num[i].wei; vis[fu]=fv; vet[num[i].x].push_back(Node(num[i].y, num[i].wei)); vet[num[i].y].push_back(Node(num[i].x, num[i].wei)); } } memset(sum,0,sizeof(sum)); res=0; Dfs(1,0); double exp = (double)(res) / (double)(n); exp = exp / (double)(n - 1) * 2.0; printf("%lld %.2lf\n", cnt, exp); } return 0; }
2016 Multi-University Training Contest 1 A
标签:最小 clear roo names amp 期望 ems 算法 生成树
原文地址:https://www.cnblogs.com/xtuteam222/p/9157952.html