中山紀念中學NOIP2012 Fortuna 系列模擬賽 input solution
阿新 • • 發佈:2017-09-08
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 charView Codec=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 }
中山紀念中學NOIP2012 Fortuna 系列模擬賽 input solution