博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu4424 Conquer a New Region 并查集/类似最小生成树
阅读量:6368 次
发布时间:2019-06-23

本文共 2437 字,大约阅读时间需要 8 分钟。

The wheel of the history rolling forward, our king conquered a new region in a distant continent.

There are N towns (numbered from 1 to N) in this region connected by several roads. It's confirmed that there is exact one route between any two towns. Traffic is important while controlled colonies are far away from the local country. We define the capacity C(i, j) of a road indicating it is allowed to transport at most C(i, j) goods between town i and town j if there is a road between them. And for a route between i and j, we define a value S(i, j) indicating the maximum traffic capacity between i and j which is equal to the minimum capacity of the roads on the route. 
Our king wants to select a center town to restore his war-resources in which the total traffic capacities from the center to the other N - 1 towns is maximized. Now, you, the best programmer in the kingdom, should help our king to select this center.

题意:有若干个城市,城市之间有边,边有容量,现在要求一个城市,使它到所有城市的总运量最大,到某一城市的运量等于相互路径上的最小容量。

由于运量是由最小容量限制的,所以我们可以先构建一颗最大生成树,边构建树边计算权值。将边从大到小排序之后,每次将最大权的边进行合并,合并的两个块内部的边都是在之前合并的,因此边权一定比当前合并的边权大,所以这两块之间运输的相互运量均等于当前边的边权,这样就可以边合并边计算合并后的最大运量,即等于某一边的最大运量加上边权乘另一边的点数个数,两边取最大值即为合并后的最大权值。

1 #include
2 #include
3 #include
4 #include
5 using namespace std; 6 typedef long long ll; 7 const int INF=0x3f3f3f3f; 8 const int mod=1e9+7; 9 const int maxn=2e6+5;10 11 struct seg{12 int a,b;13 ll v;14 bool operator <(const seg x)const{15 return v>x.v;16 }17 }s[maxn];18 19 int fa[maxn];20 ll sz[maxn];21 ll ma[maxn],ans;22 int n;23 24 int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);}25 26 void unio(int i){27 int x=s[i].a,y=s[i].b;28 ll v=s[i].v;29 int X=find(x),Y=find(y);30 ll nx=ma[X]+v*sz[Y];31 ll ny=ma[Y]+v*sz[X];32 if(nx>=ny){33 fa[Y]=X;34 sz[X]+=sz[Y];35 ma[X]=nx;36 if(nx>ans)ans=nx;37 }38 else{39 fa[X]=Y;40 sz[Y]+=sz[X];41 ma[Y]=ny;42 if(ny>ans)ans=ny;43 }44 }45 46 void init(){47 ans=0;48 for(int i=0;i<=n+5;++i)fa[i]=i;49 for(int i=0;i<=n+5;++i)sz[i]=1;50 for(int i=0;i<=n+5;++i)ma[i]=0;51 }52 53 int main(){54 while(scanf("%d",&n)!=EOF){55 if(n==1){printf("0\n");continue;}56 init();57 for(int i=1;i
View Code

 

转载于:https://www.cnblogs.com/cenariusxz/p/6598272.html

你可能感兴趣的文章
判断用户密码是否在警告期内(学习练习)
查看>>
sp_executesql的执行计划会被重用(转载)
查看>>
禅道项目管理软件插件开发
查看>>
Linux系统各发行版镜像下载
查看>>
JS获取键盘按下的键值event.keyCode,event.charCode,event.which的兼容性
查看>>
查看ORACLE 数据库及表信息
查看>>
腾讯、百度、阿里面试经验—(1) 腾讯面经
查看>>
Codeforces Round #374 (Div. 2) D. Maxim and Array 贪心
查看>>
HTML DOM 教程Part1
查看>>
GBDT的基本原理
查看>>
MySQL修改root密码的多种方法(转)
查看>>
MongoDB 基础命令——数据库表的增删改查——遍历操作表中的记录
查看>>
.NET Core 跨平台发布(dotnet publish)
查看>>
Activity入门(一)
查看>>
CentOS下如何从vi编辑器插入模式退出到命令模式
查看>>
Mysql索引的类型
查看>>
Eclipse debug模式 总是进入processWorkerExit
查看>>
Nginx的https配置记录以及http强制跳转到https的方法梳理
查看>>
[每天五分钟,备战架构师-1]操作系统的类型和结构
查看>>
springcloud(十三):Eureka 2.X 停止开发,但注册中心还有更多选择:Consul 使用详解...
查看>>