LightOJ1257 Farthest Nodes in a Tree (II)(树的点分治)
题目给一棵树,边带有权值,求每一点到其他点路径上的最大权和。
树上任意两点的路径都可以看成是经过某棵子树根的路径,即路径权=两个点到根路径权的和,于是果断树分治。
对于每次分治的子树,计算其所有结点到根的距离;对于每个结点,找到另一个离根最远的且与该结点路径过根的结点,二者的距离和就是这个点在过这棵子树的根能到的最远距离。
现在问题就是怎么比较快地找到这另一个最远距离的点。。两点路径过根,说明两点间不存在一点是另一点的祖先。。我一开始还想用DFS序+线段树来着。。想了想,想出了线性的算法:
记录每个结点属于根的哪个儿子,把当前分治子树的所有结点以属于根的哪个儿子分组,对于每个结点对应过根的结点就不能在同一组要到别的组找,而且肯定是某个组里面根距离最大的值的那个结点。通过计算每个组里面结点到根的最大值作为组的值,以及这些组的最大值和次大值,就OK了。
好难描述= =反正这样这题就用树分治解决了,时间复杂度O(nlogn)。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF (1<<29)
#define MAXN 33333
struct Edge{
int u,v,w,next;
}edge[MAXN<<];
int NE,head[MAXN];
void addEdge(int u,int v,int w){
edge[NE].u=u; edge[NE].v=v; edge[NE].w=w;
edge[NE].next=head[u]; head[u]=NE++;
} bool vis[MAXN]; int size[MAXN];
void getSize(int u,int fa){
size[u]=;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v] || v==fa) continue;
getSize(v,u);
size[u]+=size[v];
}
}
int centre,mini;
void getCentre(int u,int fa,int &tot){
int res=tot-size[u];
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v] || v==fa) continue;
getCentre(v,u,tot);
res=max(res,size[v]);
}
if(mini>res){
mini=res;
centre=u;
}
}
int getCentre(int u){
getSize(u,u);
mini=INF;
getCentre(u,u,size[u]);
return centre;
} int n,ans[MAXN];
int dn,dx[MAXN],dy[MAXN],mx1,mx2,belong[MAXN],mx[MAXN];
void dfs(int u,int fa,int dist,int &gp){
dx[dn]=u; dy[dn]=dist; dn++;
belong[u]=gp;
mx[gp]=max(mx[gp],dist);
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v] || v==fa) continue;
dfs(v,u,dist+edge[i].w,gp);
}
}
void conquer(int u){
dn=; mx1=; mx2=-INF;
dx[dn]=u; dy[dn]=; dn++;
belong[u]=u;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v]) continue;
mx[v]=-INF;
dfs(v,u,edge[i].w,v);
if(mx1<mx[v]) mx2=mx1,mx1=mx[v];
else if(mx2<mx[v]) mx2=mx[v];
}
for(int i=; i<dn; ++i){
if(mx[belong[dx[i]]]!=mx1) ans[dx[i]]=max(ans[dx[i]],dy[i]+mx1);
else ans[dx[i]]=max(ans[dx[i]],dy[i]+mx2);
}
} void divide(int u){
u=getCentre(u);
vis[u]=;
conquer(u);
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v]) continue;
divide(v);
}
}
int main(){
int t,a,b,c;
scanf("%d",&t);
for(int cse=; cse<=t; ++cse){
NE=;
memset(head,-,sizeof(head));
scanf("%d",&n);
for(int i=; i<n; ++i){
scanf("%d%d%d",&a,&b,&c);
addEdge(a,b,c); addEdge(b,a,c);
}
memset(vis,,sizeof(vis));
for(int i=; i<n; ++i) ans[i]=-INF;
divide();
printf("Case %d:\n",cse);
for(int i=; i<n; ++i) printf("%d\n",ans[i]);
}
return ;
}
LightOJ1257 Farthest Nodes in a Tree (II)(树的点分治)的更多相关文章
- lght oj 1257 - Farthest Nodes in a Tree (II) (树dp)
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1257 跟hdu2196一样,两次dfs //#pragma comment(l ...
- lightoj 1094 Farthest Nodes in a Tree 【树的直径 裸题】
1094 - Farthest Nodes in a Tree PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: ...
- light oj 1094 Farthest Nodes in a Tree(树的直径模板)
1094 - Farthest Nodes in a Tree problem=1094" style="color:rgb(79,107,114)"> probl ...
- LightOJ 1094 - Farthest Nodes in a Tree(树的直径)
http://acm.hust.edu.cn/vjudge/contest/121398#problem/H 不是特别理解,今天第一次碰到这种问题.给个链接看大神的解释吧 http://www.cnb ...
- Farthest Nodes in a Tree ---LightOj1094(树的直径)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1094 Given a tree (a connected graph with no ...
- LightOJ1094 - Farthest Nodes in a Tree(树的直径)
http://lightoj.com/volume_showproblem.php?problem=1094 Given a tree (a connected graph with no cycle ...
- Farthest Nodes in a Tree (求树的直径)
题目链接,密码:hpu Description Given a tree (a connected graph with no cycles), you have to find the farthe ...
- lightoj1094 - Farthest Nodes in a Tree
1094 - Farthest Nodes in a Tree PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limi ...
- E - Farthest Nodes in a Tree
Given a tree (a connected graph with no cycles), you have to find the farthest nodes in the tree. Th ...
随机推荐
- XSS代码触发条件,插入XSS代码的常用方法
1.脚本插入 (1)插入javascript和vbscript正常字符. 例1:<img src=”javascript:alert(/xss/)”> 例2:<table backg ...
- FineUI第五天---按钮控件
按钮控件 <x:Button runat="server" ID="按下" Text="按下"></x:Button> ...
- WPF 样式和行为
样式(style):组织和重用格式化选项的重要工具,将细节如边距.字体.字号等信息封装起来,然后再需要的地方通过属性来应用样式. 行为(behavior):封装一些通用的UI行为,如拖动,缩放元素的代 ...
- HDU 1707 简单模拟 Spring-outing Decision
Spring-outing Decision Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- [ruby on rails] 跟我学之(1)环境搭建
环境: ubuntu 12.04 (64bit) 代理: 自己最好弄一个代理. 环境配置指令如下: sudo apt-get update sudo apt-get install curl \cur ...
- 【OpenStack】OpenStack系列10之Horizon详解
一.参考其他资料即可.可以采用haproxy+apache+horizon方式部署,haproxy/httpd支持ssl.
- 《ASP.NET MVC4 WEB编程》学习笔记------Web API 续
目录 ASP.NET WEB API的出现缘由 ASP.NET WEB API的强大功能 ASP.NET WEB API的出现缘由 随着UI AJAX 请求适量的增加,ASP.NET MVC基于Jso ...
- 70 数组的Kmin算法和二叉搜索树的Kmin算法对比
[本文链接] http://www.cnblogs.com/hellogiser/p/kmin-of-array-vs-kmin-of-bst.html [分析] 数组的Kmin算法和二叉搜索树的Km ...
- 【转】SQL删除重复记录,只保留其中一条
SQL:删除重复数据,只保留一条用SQL语句,删除掉重复项只保留一条在几千条记录里,存在着些相同的记录,如何能用SQL语句,删除掉重复的呢 1.查找表中多余的重复记录,重复记录是根据单个字段(peop ...
- python 将pdf分页后插入至word中
所用技术 1. python编程基础 2. 使用pyPdf 3. 使用python操作word 4. 正则表达式的使用 5. windows的bat编程 下面是一个pyPdf库使用的示例: from ...