首页 > 其他 > 详细

中山纪念中学NOIP2012 Fortuna 系列模拟赛 input solution

时间:2017-09-08 20:23:45      阅读:640      评论:0      收藏:0      [点我收藏+]

题意

给你一棵带边权的树,然后这棵树是某个完全图唯一的最小生成树。问原来的完全图中所有边可能的最小边权和是多少。完全图是任意两个点之间都有边相连的图。

Solution

n^3算法:kruscal 逆推枚举+并查集

O(n):带权并查集+sort

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #define ll long long
 5 using namespace std;
 6 inline void read(ll &k)
 7 {
 8     char c=getchar();ll f=1;k=0;
 9     while (c<0||c>9)c==-&&(f=-1),c=getchar();
10     while (c>=0&&c<=9)k=k*10+c-0,c=getchar();
11     k*=f;
12 }
13 const int maxn=20000+10;
14 struct aa{
15     ll a,b,w;
16 }qaq[maxn];
17 bool cmp(aa i,aa j)
18 {
19     return i.w<j.w;
20 }
21 ll T,n,sum[maxn],fa[maxn],a[maxn],b[maxn],w[maxn],ans;
22 ll gf(ll now)
23 {
24     return fa[now]==now?now:fa[now]=gf(fa[now]);
25 }
26 int main()
27 {
28     freopen("input.in","r",stdin);
29     freopen("input.out","w",stdout);
30     read(T);
31     while (T--)
32     {
33         ans=0;
34         read(n);
35         for (int i=1;i<=n;i++)fa[i]=i;
36         for (int i=1;i<=n;i++)sum[i]=1;
37         for (int i=1;i<n;i++)
38         {
39             read(qaq[i].a);
40             read(qaq[i].b);
41             read(qaq[i].w);
42         }
43         sort(qaq+1,qaq+n,cmp);
44         for (int i=1;i<n;i++)
45         {
46             ll aa=gf(qaq[i].a),bb=gf(qaq[i].b);
47             ans+=qaq[i].w+(qaq[i].w+1)*(sum[aa]*sum[bb]-1);
48             fa[aa]=fa[bb];
49             sum[bb]+=sum[aa];
50         }
51     //    if (!T)cout << sum[1] << " "<<sum[2]<<" "<<sum[3]<<endl;
52         printf("%lld\n",ans);
53     }
54 }
View Code

 

中山纪念中学NOIP2012 Fortuna 系列模拟赛 input solution

原文:http://www.cnblogs.com/mczhuang/p/7496125.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!