hdu 4679 树的直径
/*
题目大意:给n个点n-1条边的树,求删除哪条边时两个树中最大的直径与边权的乘积最小。
树的直径(Diameter)是指树上的最长简单路。
直径的求法:两遍BFS (or DFS)
若删除的边不是直径上的那么花费为max_len*wi
若删除的边是直径上的那么花费为max(dp[u][2],dp[v][2])*wi
*/
#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std; const int maxn=;
int dep[maxn],ans[maxn],father[maxn],max_len;//ans下标对应边的编号
int dp[maxn][];//j=0存i节点的到子树中的最长路,j=1存次长路,j=2存直径
bool vis[maxn];//标记是否为直径上的点
inline int max(int a,int b){return a>b?a:b;}
struct node
{
int id,w,v;
node(int id=,int w=,int v=):id(id),w(w),v(v){}
};
vector<node> f[maxn]; void dfs_dep(int u,int pre)//找最长路
{
for(int i=;i<f[u].size();i++)
{
int v=f[u][i].v;
if(v==pre) continue;
dep[v]=dep[u]+;
father[v]=u;
dfs_dep(v,u);
}
return ;
} void dfs(int u,int pre)
{
dp[u][]=dp[u][]=dp[u][]=;
for(int i=;i<f[u].size();i++)
{
int v=f[u][i].v;
if(v==pre) continue;
dfs(v,u);
int temp=dp[v][]+;
if(temp>dp[u][])
{
dp[u][]=dp[u][];dp[u][]=temp;
}
else if(temp>dp[u][])
dp[u][]=temp;
dp[u][]=max(dp[u][],dp[v][]);//u在子树直径边上与不再直径边上
}
dp[u][]=max(dp[u][],dp[u][]+dp[u][]);//u在子树直径中与不再直径中
} void solve(int u,int pre)
{
for(int i=;i<f[u].size();i++)
{
int v=f[u][i].v,id=f[u][i].id,w=f[u][i].w;
if(v==pre) continue;
solve(v,u);
//在树的直径上
if(vis[u] && vis[v])
ans[id]=max(ans[id],w*dp[v][]);
else ans[id]=w*max_len;
}
} int main()
{
int t,i,n,icase=,a,b,w;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=;i<=n;i++) f[i].clear();
for(i=;i<n;i++)
{
scanf("%d%d%d",&a,&b,&w);
f[a].push_back(node(i,w,b));
f[b].push_back(node(i,w,a));
}
int st,ed=,temp;
dfs_dep(ed,-);
for(i=;i<=n;i++)
if(dep[ed]<dep[i]) ed=i;
dep[st=ed]=;
dfs_dep(st,-);
ed=st;
for(i=;i<=n;i++)
if(dep[ed]<dep[i]) ed=i;
max_len=dep[ed];
memset(vis,,sizeof(vis));
father[st]=-;temp=ed;
while(father[temp]!=-)
vis[temp]=true,temp=father[temp];
memset(ans,,sizeof(ans));
dfs(st,-);solve(st,-);
dfs(ed,-);solve(ed,-);
temp=;
for(i=;i<n;i++)
if(ans[i]<ans[temp]) temp=i;
printf("Case #%d: %d\n",++icase,temp);
}
return ;
}
hdu 4679 树的直径的更多相关文章
- hdu 3721 树的直径
思路:枚举+树的直径 #include<iostream> #include<cstring> #include<cstdio> #include<algor ...
- hdu 4514(树的直径+并查集)
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- Warm up HDU - 4612 树的直径
题意:给出n个点和m条边的无向图,存在重边,问加一条边以后,剩下的桥的数量最少为多少. 题解: 你把这个无向图缩点后会得到一个只由桥来连接的图(可以说这个图中的所有边都是桥,相当于一棵树),然后我们只 ...
- hdu 4607 树的直径
思路:利用dfs遍历整棵树,找出最长子树与次长子树,两者的和最大就是直径. 若k值小于直径就输出k-1,否则输出(k-d-1)*2+d; #include<iostream> #inclu ...
- Warm up HDU - 4612( 树的直径 边双连通分量)
求在图中新建一条边后 剩下的最少的桥的数量..先tarjan求桥的数量..然后缩点..以连通分量为点建图 bfs求直径 最后用桥的数量减去直径即为答案 bfs求直径 https://www.cnb ...
- hdu 4679 树状dp
思路:我们其实只需要枚举每条边,求得最小值就行了. 先dfs算出每个节点作为根时,其子树的最长路径,以及进过该节点的最长,次长,第三长路径. 然后在次dfs枚举求出切断某条边,求出这条边的两个端点为子 ...
- hdu 4679 Terrorist’s destroy 树的直径+dp
题意:给你一棵树,每条边都有值W,然后问你去掉一条边,令val = w*max(两颗新树的直径),求val最小值~ 做法,先求树的直径,然后算出直径上每个点的最长枝条长度.这样对于每一条边,假如是枝条 ...
- hdu 4607 Park Visit 求树的直径
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n) ...
- 【HDU 4612 Warm up】BCC 树的直径
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...
随机推荐
- scrapy--matplotlib
昨天晚上看了一些关于保存文件的相关资料,早早的睡了,白天根据网上查找的资料,自己再捡起来.弄了一上午就爬取出来了,开心!!!好吧,让我们开始 老规矩,先上图.大家也赶快行动起来 分类文件: 文件内co ...
- 吴恩达DeepLearning 第一课第四周随笔
第四周 4.1深度神经网络符号约定 L=4______(神经网络层数) 4.2 校正矩阵的维数 校正要点:,, dZ,dA,dW,db都与它们被导数(Z,A,W,b)的维数相同 4.3 为什么使用 ...
- Git-补丁文件交互
版本库间的交互是通过git push和/或git pull命令实现的,这是Git最主要的交互模式,但并不是全部.使用补丁文件是另外一种交互方式,适用于参与者众多的大型项目进行分布式开发. 创建补丁 G ...
- Ubuntu 14.10 配置JDK + J2EE
本文仅作为本人在Ubuntu 14.10下安装JDK + J2EE的一个记录: 安装JDK 从Oracle的官网下载jdk-7u75-linux-x64.tar.gz 将jdk-7u75-linux- ...
- 20145202马超《java程序设计》第一周学习总结
这两天的学习让我对java有了初步的了解. 1.java是SUN公司推出的面相网络的编程语言. 特点:完全面向对象,与平台无关,跨平台性(例如c++只能在windows上执行,然而java并没有这些限 ...
- Spring_依赖注入思想
Ioc(Inversion of Control) 控制反转,DI(Dependncy Injection)依赖注入,其实是指同一种思想.举例说明: 张三在某公司负责供水问题.有两种形式,第一种老板指 ...
- python学习笔记十二:类的定义
demo #!/usr/bin/python class Person: name = 'jim' age = 25 def say(self): print 'My name is ' + self ...
- global js库
var GLOBAL = {}; GLOBAL.namespace = function(str) { var arr = str.split("."), o = GLOBAL,i ...
- python 学习分享-paramiko模块
paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Solaris, BS ...
- 孤荷凌寒自学python第三十二天python的代码块中的异常的捕获
孤荷凌寒自学python第三十二天python的代码块中的异常的捕获 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天简单了解了Python的错误陷阱,了解到其与过去学过的其它语言非常类似 ...