HDU
来源:互联网 发布:python批处理文件 编辑:程序博客网 时间:2024/06/05 09:09
题意:
给出n个点和m条边,每条边有一个权值,题目保证每条边的权值都不一样,求出一个权值最小生成树,并且求出任意选择n个点中的两点之间距离的权值的最小期望。
思路:
最小生成树没什么好说的,因为每条边权值不一样,所以可以保证求出的最小生成树一定只有一个解。按照求出的最小生成树建一棵树,所谓期望=任意两点之间的距离和/C(n,2),这样只要求出任意选择两个点的所有情况的距离和即可,dp一下。
代码:
#include <bits/stdc++.h>using namespace std;const int MAXN = 1e5 + 10;const int MAXM = 1e6 + 10;struct Edge { int u, v, w; bool operator < (const Edge &rhs) const { return w < rhs.w; }} e[MAXM];struct node { int v, w;};int n, m;int pa[MAXN];vector <node> tree[MAXN];void init() { for (int i = 1; i <= n; i++) { pa[i] = i; tree[i].clear(); }}int Find(int x) { return x == pa[x] ? x : pa[x] = Find(pa[x]);}long long kruskal() { init(); long long res = 0; sort(e + 1, e + 1 + m); for (int i = 1; i <= m; i++) { int pu = Find(e[i].u), pv = Find(e[i].v); if (pu != pv) { pa[pu] = pv; int u = e[i].u, v = e[i].v, w = e[i].w; tree[u].push_back((node){v, w}); tree[v].push_back((node){u, w}); res += w; } } return res;}int sum[MAXN];double expe = 0;int dfs(int u, int pre) { sum[u] = 1; int cnt = tree[u].size(); for (int i = 0; i < cnt; i++) { int v = tree[u][i].v, w = tree[u][i].w; if (v == pre) continue; sum[u] += dfs(v, u); expe += (double)sum[v] * (n - sum[v]) * w; } return sum[u];}int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w); printf("%I64d", kruskal()); expe = 0; dfs(1, -1); double tmp = (double)n * (n - 1) / 2.0; printf(" %.2f\n", expe / tmp); } return 0;}
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- maven.pom.xml详解
- 浅谈UML中的聚合与组合
- 版本控制SVN工具的使用
- webpack15分钟搞定
- nVIDIA Jetson TX1 NFS服务搭建
- HDU
- SpringToolSuite初始化配置
- git 创建分支 合并分支
- 物理综合
- 亿级Web系统搭建——单机到分布式集群
- 获取本应用apk文件md5
- 用于stm32Discovery的图像转代码取模小工具
- 如何更改Win32生成exe文件的图标
- 解决java.lang.NoClassDefFoundError: com.android.tools.fd.runtime.AppInfo