HDU 4424 Conquer a New Region and query set, hdu4424
Given n points and n-1 edges, the maximum carrying capacity between a and B is the minimum carrying capacity between a and B. Take a certain point as the center, and calculate the maximum value of the sum of carrying capacity.
Since the carrying capacity between a and B is the minimum value of the carrying capacity between them, the carrying capacity between two points is first sorted from large to small. Each merge has two sets, A and B. The cost between them is the current minimum. If B is merged to A, the total CARRYING CAPACITY OF A is the total carrying capacity before A plus, the load between two equal parts (cost [A] = cost [A] + num [B] * cost.
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int inf=1000000000;const int maxn=200005;int f[maxn];ll num[maxn],cost[maxn];struct Branch{ int a; int b; ll cost;}bra[maxn];bool cmp(Branch a,Branch b){ return a.cost>b.cost;}int Find(int x){ if(x!=f[x]) f[x]=Find(f[x]); return f[x];}ll Function(int n){ for(int i=0;i<n-1;i++) { int a=Find(bra[i].a); int b=Find(bra[i].b); if(cost[a]+num[b]*bra[i].cost>=cost[b]+num[a]*bra[i].cost) { f[b]=a; cost[a]+=num[b]*bra[i].cost; num[a]+=num[b]; } else { f[a]=b; cost[b]+=num[a]*bra[i].cost; num[b]+=num[a]; } } return cost[Find(1)];}int main(){ //freopen("in.txt","r",stdin); int n; while(scanf("%d",&n)!=EOF) { for(int i=0;i<=n;i++) { f[i]=i; num[i]=1; } memset(cost,0,sizeof(cost)); for(int i=0;i<n-1;i++) scanf("%d%d%I64d",&bra[i].a,&bra[i].b,&bra[i].cost); sort(bra,bra+n-1,cmp); printf("%I64d\n",Function(n)); } return 0;}