zoj Conquer a New Region 并查集

本文通过实例解析如何运用并查集解决特定图论问题,涉及选择中心城镇以最大化距离之和,通过排序与合并操作实现最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题是在CF上看到的~http://vjudge.net/contest/view.action?cid=49082#problem/C,主要是练习并查集

先说一下题意:有n个城镇,有n-1条边使得这n个城镇构成一个连通图,每条边都有一个权值。

现在的要求是:从n个城镇中选一个中心城镇,使得中心城镇到其他n-1个城镇的D值和最大,D值是城镇i 到 城镇 j route上最小权值的road..

比如 城镇3到城镇4 权值是90. 城镇4到城镇5权值是80,那么3 到5 的D值就是80.

可以用神奇的并查集解决这一问题,因为有n-1条边,所以先把边按从大到小排序,然后一个个并;

具体看代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
struct Node
{
 int cnt;
 long long sum;   
}node[200010];
struct Edge
{
 int a,b,c;
}edge[200010];
int f[200010];
int cmp(Edge a,Edge b)
{
  return a.c>b.c;  
}
int find(int x)
{
 if(f[x]!=x)
   f[x]=find(f[x]);
 return f[x];
}
int main()
{
 int n;
 while(cin>>n)
 {
  for(int i=1;i<=n;i++)
  {
    node[i].cnt=1;
    node[i].sum=0;
    f[i]=i;  
  }
  for(int i=0;i<n-1;i++)
    cin>>edge[i].a>>edge[i].b>>edge[i].c;
  sort(edge,edge+n-1,cmp);
  for(int i=0;i<n-1;i++)
  {
    int f1=find(edge[i].a);
    int f2=find(edge[i].b);
    long long temp1=node[f1].sum+(long long )edge[i].c*node[f2].cnt;
    long long temp2=node[f2].sum+(long long )edge[i].c*node[f1].cnt;
    if(temp1>temp2)
    {
      f[f2]=f1;
      node[f1].sum=temp1;
      node[f1].cnt+=node[f2].cnt;
        
    }
    else
    {
      f[f1]=f2;
      node[f2].sum=temp2;
      node[f2].cnt+=node[f1].cnt;  
    }
  }
  printf("%lld\n",node[find(1)].sum);
 }
 return 0;   
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值