当前位置: 代码迷 >> 综合 >> HDU 4424Conquer a New Region(并查集)
  详细解决方案

HDU 4424Conquer a New Region(并查集)

热度:39   发布时间:2023-12-06 19:23:07.0

题意:

给出一个树形图和边权值,边权值是容量,问把某个点作为首都,向其他n-1个点运输货物,货物容量不超过路径上的边权值;问可以输出的最大货物是多少?


思路:

因为限制条件是路径上的最小值,那么我们按价值排序,从大到小排,就可以避免这个问题了,然后利用并查集来完成,对于两个集合,左集合的价值总和为A,右集合的价值总和为B,现在有一条路径连接这两个集合,那么我们考虑的是将A合并到B还是将B合并到A,我们可以这么比较,连接这两个集合的路径肯定是目前最小的价值,如果A集合元素个数为Ai,那么将A合并到B则B需要加A*Ai,反过来A则加B*Bi,比较哪个大就行了,因为它们一定是合并成一块了,价值大的留下


#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define N 200005
struct Edge
{int u, v;LL w;bool operator < (const Edge &other) const{return w>other.w;}
}edge[N];
int fa[N];
LL sum[N], num[N];
int getf(int x)
{return fa[x]==x?x:fa[x]=getf(fa[x]);
}
LL solve(int n)
{for(int i=0; i<n-1; i++){int u=getf(edge[i].u);int v=getf(edge[i].v);if(sum[u]+num[v]*edge[i].w>=sum[v]+num[u]*edge[i].w){fa[v]=u;sum[u]+=num[v]*edge[i].w;num[u]+=num[v];}else{fa[u]=v;sum[v]+=num[u]*edge[i].w;num[v]+=num[u];}}return sum[getf(1)];
}
int main()
{int n;while(scanf("%d", &n)!=EOF){for(int i=0; i<n-1; i++){int u, v, w;scanf("%d%d%d", &u, &v, &w);edge[i].u=u;edge[i].v=v;edge[i].w=w;}sort(edge, edge+n-1);for(int i=1; i<=n; i++){fa[i]=i;sum[i]=0;num[i]=1;}LL ans=solve(n);printf("%I64d\n", ans);}return 0;
}


  相关解决方案