码迷,mamicode.com
首页 > 其他好文 > 详细

2016年暑期多校【1】

时间:2016-07-20 22:42:39      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:

1、【HDU 5723】Abandoned country(最小生成树+树形dp)

题意:n(n≤100000)个城市,m(m≤1000000)条路,要修建(n-1)条路使这n个城市连通,题目中告诉我们修建每条路的费用,需要求两个问题:1、修建(n-1)条路的最小费用 2、路修建好了之后,任意两点之间的长度的期望

解题思路:

修建(n-1)条路的最小费用==>最小生成树

路修建好了之后,任意两点之间的长度的期望:实际上就是求任意两点之间的平均距离。对于边X,求所有可能的路径经过此边的次数:设这条边两端的点数分别为A和B, 点A的子树的大小是size(A),设点B的子树大小是size(B),【这里所说的子树都是不经过边X的】那么这条边被经过的次数就是size(A)*size(B),它对总的距离和的贡献就是

(size(A)*size(B)*边X的长度)。求出所有边的贡献总和然后除以(n*(n-1)/2)就是所求值

long long没有处理好,wa了很多次。

技术分享
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <string>
 6 #include <vector>
 7 using namespace std;
 8 #define ll long long
 9 const int N=1e6+10;
10 
11 struct node{
12     int u, v, w;
13     friend bool operator < (const node n1, const node n2){
14         return n1.w<n2.w;
15     }
16 }a[2*N];
17 
18 struct Node{
19     int v, len;
20     Node(int _v, int _len):v(_v), len(_len){}
21 };
22 
23 int fa[N];
24 vector<Node>vec[N];
25 int find(int x)
26 {
27     return fa[x]=(fa[x]==x?x:find(fa[x]));
28 }
29 ll kruskal(int n, int m)
30 {
31     ll ans=0;
32     int tmp=0;
33     for(int i=1; i<=n; i++) fa[i]=i, vec[i].clear();
34     for(int i=0; i<m; i++)
35     {
36         if(tmp>=n-1) break;
37         int ui=find(a[i].u), vi=find(a[i].v);
38         if(ui!=vi)
39         {
40             tmp++, fa[vi]=ui, ans+=(ll)a[i].w;
41             vec[a[i].u].push_back(Node(a[i].v, a[i].w));
42             vec[a[i].v].push_back(Node(a[i].u, a[i].w));
43         }
44     }
45     return ans;
46 }
47 
48 ll dis[N];
49 int sum[N];
50 int n;
51 void dfs(int u, int p){
52     
53     sum[u]=1;
54     for(int i=0; i<(int)vec[u].size(); i++){
55         int vi = vec[u][i].v;
56         int wi = vec[u][i].len;
57         if(vi==p) continue;
58         dfs(vi, u);
59         sum[u]+=sum[vi];
60         dis[u] += dis[vi]+((ll)sum[vi]*(n-sum[vi]))*wi;
61     }
62     
63 }
64 
65 int main(){
66     int t;
67     scanf("%d", &t);
68     while(t--){
69         int m, lena=0;
70         scanf("%d%d", &n, &m);
71         int ui, vi, wi;
72         for(int i=0; i<m; i++){
73             scanf("%d%d%d", &ui, &vi, &wi);
74             a[lena].u=ui, a[lena].v=vi, a[lena].w=wi, lena++;
75             a[lena].u=vi, a[lena].v=ui, a[lena].w=wi, lena++;
76         }
77         sort(a, a+lena);
78         ll ans = kruskal(n, lena);
79         memset(dis, 0, sizeof(dis));
80         dfs(1, -1);
81         ll s = (ll)n*(n-1)/2;
82         printf("%lld %.2lf\n", ans, dis[1]*1.0/s);
83     }
84     return 0;
85 }
View Code

 

2016年暑期多校【1】

标签:

原文地址:http://www.cnblogs.com/yscc/p/5689827.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!