1. 程式人生 > >中山紀念中學NOIP2012 Fortuna 系列模擬賽 input solution

中山紀念中學NOIP2012 Fortuna 系列模擬賽 input solution

size noip inpu hid kruscal getchar() for logs etc

題意

給你一棵帶邊權的樹,然後這棵樹是某個完全圖唯一的最小生成樹。問原來的完全圖中所有邊可能的最小邊權和是多少。完全圖是任意兩個點之間都有邊相連的圖。

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