zoj 3659 Conquer a New Region The 2012 ACM-ICPC Asia Changchun Regional Contest
Conquer a New Region
Time Limit: 5 Seconds Memory Limit: 32768 KB
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.
Input
There are multiple test cases.
The first line of each case contains an integer N. (1 ≤ N ≤ 200,000)
The next N - 1 lines each contains three integers a, b, c indicating there is a road between town a and town b whose capacity is c. (1 ≤ a, b ≤ N, 1 ≤ c ≤ 100,000)
Output
For each test case, output an integer indicating the total traffic capacity of the chosen center town.
Sample Input
4
1 2 2
2 4 1
2 3 1
4
1 2 1
2 4 1
2 3 1
Sample Output
4
3
Contest: The 2012 ACM-ICPC Asia Changchun Regional Contest
题意:给你一棵树,s[i,j]表示从i点到j点的路径权值的最小值,f[i]表示i点到树上除i外所有的点j的s[i,j]。求最大的f[i]是多少。
思路1:先把所有边按从大到小排序。一条边一条边地加入树中,每次合并两个集合(其实就是两个并查集,也就是两棵树),f[i]表示以i为根的这棵子树每个节点都能获得比原来多f[i]的值。不断合并两个集合,然后用类似并查集压缩路径的方法压缩f[i]。最后就能得到所有f[i]的值,再从中选一个最大的,即答案。
/*
* Author: Joshua
* Created Time: 2014年10月05日 星期日 10时01分55秒
* File Name: e.cpp
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 200001
typedef long long LL;
int n;
struct edge
{
int u,v,w;
bool operator < (const edge& p) const
{
return w>p.w;
}
void input()
{
scanf("%d%d%d",&u,&v,&w);
}
} e[maxn]; int fa[maxn],size[maxn];
bool vis[maxn];
LL f[maxn];
void init()
{
for (int i=;i<n;++i)
e[i].input();
sort(e+,e+n);
for (int i=;i<=n;++i)
{
fa[i]=i;
size[i]=;
}
memset(f,,(n+)<<);
memset(vis,,n+);
} int gf(int x,int t)
{
if (vis[x]) return f[x];
if (t) vis[x]=true;
if (fa[x]==x) return x;
int temp,tf=fa[x];
temp=gf(tf,t);
if (!t)
{
if (temp!=tf) f[x]+=f[tf];
}
else f[x]+=f[tf];
return fa[x]=temp;
} void solve()
{
int u,v,fu,fv;
LL ans=,w;
for (int i=;i<n;++i)
{
u=e[i].u; v=e[i].v; w=e[i].w;
fu=gf(u,);
fv=gf(v,);
f[fu]+=size[fv]*w;
f[fv]+=(size[fu]*w-f[fu]);
size[fu]+=size[fv];
fa[fv]=fu;
}
for (int i=;i<=n;++i)
{
if (!vis[i]) u=gf(i,);
ans=max(ans,f[i]);
}
cout<<ans<<endl;
} int main()
{
while (scanf("%d",&n)!=EOF)
{
init();
solve();
}
return ;
}
思路2:类似于思路1,但既然我们只要求一个最大的,那么其他的值求出来就很浪费了。因此我们将思路1中的f[i]改为以i为根的并查集中,当前获得的最大值的那个点的值。因为在不断合并中,这个并查集中的每个点获得的数值都是一样的,所以当前最大的那个点肯定在最后也是最大的。因此我们做的就是每次合并两个集合,选出一个最大的。然后不断合并即可。最后的答案肯定能在最后一次合并中找出。
/*
* Author: Joshua
* Created Time: 2014年10月05日 星期日 20时01分10秒
* File Name: e.cpp
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 200001
typedef long long LL;
int n;
struct edge
{
int u,v,w;
bool operator < (const edge& p) const
{
return w>p.w;
}
void input()
{
scanf("%d%d%d",&u,&v,&w);
}
} e[maxn]; int fa[maxn],size[maxn];
LL f[maxn];
void init()
{
for (int i=;i<n;++i)
e[i].input();
sort(e+,e+n);
for (int i=;i<=n;++i)
{
fa[i]=i;
size[i]=;
}
memset(f,,(n+)<<);
} int gf(int x)
{
int &t=fa[x];
return t= ( t==x ? x:gf(t));
} void solve()
{
int u,v,fu,fv;
LL ans=,w,tu,tv;
for (int i=;i<n;++i)
{
u=e[i].u; v=e[i].v; w=e[i].w;
fu=gf(u);
fv=gf(v);
tu=f[fu]+size[fv]*w;
tv=f[fv]+size[fu]*w;
if (tu>tv)
{
fa[fv]=fu;
size[fu]+=size[fv];
f[fu]=tu;
}
else
{
fa[fu]=fv;
size[fv]+=size[fu];
f[fv]=tv;
}
}
ans=max(tu,tv);
cout<<ans<<endl;
} int main()
{
while (scanf("%d",&n)!=EOF)
{
init();
solve();
}
return ;
}
zoj 3659 Conquer a New Region The 2012 ACM-ICPC Asia Changchun Regional Contest的更多相关文章
- hdu 4424 & zoj 3659 Conquer a New Region (并查集 + 贪心)
Conquer a New Region Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online)
HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online) 题目链接http://acm.hdu.edu.cn/showp ...
- zoj 3659 Conquer a New Region
// 给你一颗树 选一个点,从这个点出发到其它所有点的权值和最大// i 到 j的最大权值为 i到j所经历的树边容量的最小值// 第一感觉是树上的dp// 后面发现不可以// 看了题解说是并查集// ...
- zoj 3659 Conquer a New Region(并查集)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4882 代码: #include<cstdio> #inc ...
- ZOJ - 4048 Red Black Tree (LCA+贪心) The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online
题意:一棵树上有m个红色结点,树的边有权值.q次查询,每次给出k个点,每次查询有且只有一次机会将n个点中任意一个点染红,令k个点中距离红色祖先距离最大的那个点的距离最小化.q次查询相互独立. 分析:数 ...
- 2016 ACM ICPC Asia Region - Tehran
2016 ACM ICPC Asia Region - Tehran A - Tax 题目描述:算税. solution 模拟. B - Key Maker 题目描述:给出\(n\)个序列,给定一个序 ...
- HDU-4432-Sum of divisors ( 2012 Asia Tianjin Regional Contest )
Sum of divisors Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- ZOJ 3545 Rescue the Rabbit(AC自动机+状压DP)(The 2011 ACM-ICPC Asia Dalian Regional Contest)
Dr. X is a biologist, who likes rabbits very much and can do everything for them. 2012 is coming, an ...
- HDU 4436 str2int(后缀自动机)(2012 Asia Tianjin Regional Contest)
Problem Description In this problem, you are given several strings that contain only digits from '0' ...
随机推荐
- 一步一步学Vue(四)
接上篇.上篇中给出了代码框架,没有具体实现,这一篇会对上篇定义的几个组件进行分别介绍和完善: 1.TodoContainer组件 TodoContainer组件,用来组织其它组件,这是react中推荐 ...
- 号称精通Java的你,是否真的名副其实
慎用精通 随着猎头行业的兴盛,一些应聘者往往可以从猎头那得到一些注意事项和过往经验.比如,在简历中切不可随意用上"精通"二字,尤其对于刚入职场的小伙伴. 因为,对于应聘者写上精通和 ...
- 【NOIP2016】Day1 T3 换教室(期望DP)
题目背景 NOIP2016 提高组 Day1 T3 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n 节课程安排在 n 个时间段上. ...
- (转)Linux(Centos)之安装Java JDK及注意事项
场景:天下事有难易乎?为之,则难者亦易矣:不为,则易者亦难矣.人之为学有难易乎?学之,则难者亦易矣:不学,则易者亦难矣. 1 准备工作 下面配置jdk的方式在具有root权限时候能够执行.如果没有ro ...
- kibana 常用查询方法
下面直接通过实例演示常用的搜索方法 转义特殊字符 + - && || ! () {} [] ^" ~ * ? : \ 注意:以上字符当作值搜索的时候需要用 \ 转义 1.在任 ...
- PHP通过phpmailer批量发送邮件功能
前端页面代码: 注意:目前发送人使用的qq邮箱支持的不是特别友好.建议使用网易 新浪 163等其他邮箱. 需要用到phpmailer包 下载地址:https://sourceforge.net/pro ...
- Python操作文件和目录
Python操作文件和目录 读写文件比较简单,有一点特别注意就好了 windows下Python默认打开的文件以gbk解码,而一般我们的文件是utf-8编码的,所以如果文本含有中文,就会出现异常或者乱 ...
- webpack学习--创建一个webpack打包流程
创建一个webpack打包流程 首先安装webpack插件 mkdir webpack-demo && cd webpack-demo npm init -y npm install ...
- proxifier配合ss,实现全局代理
proxfixer配合ss的话,基本可以实现全局代理,分应用代理,或者玩外服的游戏(一般的游戏默认不走代理,本软件可以强制应用代理) 由于ss使用的是sockets5代理,一般情况下只有浏览 ...
- Shell curl 和 wget 使用代理IP
Linux Shell 提供两个非常实用的命令来爬取网页,它们分别是 curl 和 wget curl 和 wget 使用代理 curl 支持 http.https.socks4.socks5 wge ...