题意:
n 个城市形成一棵树,每条边有权值C(i,j),任意两个点的容量S(i,j)定义为i与j 唯一通路上容量的最小值,找一个点,使得它到其他点的容量之和最大,求最大值?
思路:
贪心思路。
我们给边从大到小排序,因为是一棵树, 每个边都要处理。
因此当前枚举的边一定是当前集合中 最小的边,因此他就是容量, 我们分别让两个端点的并查集父亲 作为中心城市, 找一个大的进行合并即可。
这样枚举到最后 我们就可以得出最大容量。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 200000 + 6;
typedef long long LL;
struct Edge{
int u,v,w;
void read(){
scanf("%d %d %d",&u, &v, &w);
}
bool operator < (const Edge& rhs) const {
return w > rhs.w;
}
}p[maxn];
struct Node{
int num;
LL sum;
}nod[maxn];
int fa[maxn];
int find(int x){
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
int main(){
int n, m;
while(~scanf("%d",&n)){
m = n-1;
for (int i = 0; i < m; ++i){
p[i].read();
}
sort(p,p+m);
for (int i = 1; i <= n; ++i){
nod[i].num = 1;
nod[i].sum = 0;
fa[i] = i;
}
for (int i = 0; i < m; ++i){
int x = find(p[i].u);
int y = find(p[i].v);
LL xx = nod[x].sum + (LL)p[i].w * (LL)nod[y].num;
LL yy = nod[y].sum + (LL)p[i].w * (LL)nod[x].num;
if (xx < yy) {
swap(xx,yy);
swap(x,y);
}
fa[y] = x;
nod[x].sum = xx;
nod[x].num += nod[y].num;
}
printf("%lld\n",nod[find(1)].sum);
}
return 0;
}