tree
时间限制:1秒 内存限制: 64 MB
试题描述
对于完全图G,若有且仅有一棵最小生成树为T,则称完全图G是树T的扩展出的。给你一棵树T,找出T能扩展出的边权和最小的完全图G。
输入要求
第一行N,(2 <= N <= 10^5)表示树T的点数。 接下来N-1行,Si Ti Di 描述一条边(Si,Ti)权值为 Di。 保证输入数据构成一棵树。
输出要求
一行一个数,表示最小的图G的边权和。
输入样例
4 1 2 1 1 3 1 1 4 2
输出样例
12
知识点及提示
添加D(2,3)=2,D(3,4)=3,D(1,4)=3即可。
题目解析 :首先回顾一下Kruskal算法求最小生成树的方法 -- 将所有的边进行排序,由小到大依次尝试添加进最小生成树中。如果满足这条边的2个端点u和v不连通,那么将这条边加入最小生成树中,否则不能加入。
借鉴这种方法,将所有的边进行排序,由小到大开始添加进最小生成树。对于当前这条边的2个端点u和v,所处的2个连通块U和V之间必然是还未连通的。加入这条边之后2个才能够连通,换言之,使得这2个连通块连通的权值最小的边就是当前的u和v边。因此被排除的边就是Sum(U)*Sum(V) -1(U中取一个点,V中取一个点,然后排除u,v这条边),而这条边的权值就是w(u,v) + 1。
代码如下 :
1 #include <cstdio> 2 #include <algorithm> 3 4 #define rep(i, x) for (int i = 1; i <= x; i ++) 5 6 #define WINDOWS 7 8 using namespace std; 9 10 #ifdef WINDOWS 11 typedef __int64 int64; 12 #else 13 typedef long long int64; 14 #endif 15 16 const int Maxn = 1e5 + 1; 17 18 struct edge 19 { 20 int x, y; 21 int64 c; 22 }A[Maxn]; 23 24 int N, F[Maxn]; 25 int64 Sum[Maxn], Ans; 26 27 void Print() 28 { 29 printf("%I64d", Ans); 30 } 31 32 void Set_Combine(int x, int y) 33 { 34 F[x] = y; 35 Sum[y] += Sum[x]; 36 } 37 38 int Set_Find(int k) 39 { 40 return F[k] == k ? k : F[k] = Set_Find(F[k]); 41 } 42 43 void Set_Init() 44 { 45 rep(i, N) { F[i] = i; Sum[i] = 1; } 46 } 47 48 bool Cmp(edge a, edge b) 49 { 50 return a.c < b.c; 51 } 52 53 void Solve() 54 { 55 sort(A + 1, A + N, Cmp); 56 Set_Init(); 57 rep(i, N - 1) 58 { 59 int x = Set_Find(A[i].x), y = Set_Find(A[i].y); 60 Ans += (Sum[x] * Sum[y] - 1) * (A[i].c + 1); 61 Set_Combine(x, y); 62 } 63 } 64 65 inline void Scan(int &x) 66 { 67 char c; 68 while (c = getchar(), c < '0' || c > '9'); x = c - '0'; 69 while (c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; 70 } 71 72 inline void Scan(int64 &x) 73 { 74 char c; 75 while (c = getchar(), c < '0' || c > '9'); x = c - '0'; 76 while (c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; 77 } 78 79 void Init() 80 { 81 Scan(N); 82 rep(i, N - 1) 83 { 84 Scan(A[i].x); Scan(A[i].y); Scan(A[i].c); 85 Ans += A[i].c; 86 } 87 } 88 89 int main() 90 { 91 Init(); 92 Solve(); 93 Print(); 94 return 0; 95 }