/*
题目大意:给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 树的直径的更多相关文章

  1. hdu 3721 树的直径

    思路:枚举+树的直径 #include<iostream> #include<cstring> #include<cstdio> #include<algor ...

  2. hdu 4514(树的直径+并查集)

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  3. Warm up HDU - 4612 树的直径

    题意:给出n个点和m条边的无向图,存在重边,问加一条边以后,剩下的桥的数量最少为多少. 题解: 你把这个无向图缩点后会得到一个只由桥来连接的图(可以说这个图中的所有边都是桥,相当于一棵树),然后我们只 ...

  4. hdu 4607 树的直径

    思路:利用dfs遍历整棵树,找出最长子树与次长子树,两者的和最大就是直径. 若k值小于直径就输出k-1,否则输出(k-d-1)*2+d; #include<iostream> #inclu ...

  5. Warm up HDU - 4612( 树的直径 边双连通分量)

    求在图中新建一条边后  剩下的最少的桥的数量..先tarjan求桥的数量..然后缩点..以连通分量为点建图  bfs求直径 最后用桥的数量减去直径即为答案 bfs求直径 https://www.cnb ...

  6. hdu 4679 树状dp

    思路:我们其实只需要枚举每条边,求得最小值就行了. 先dfs算出每个节点作为根时,其子树的最长路径,以及进过该节点的最长,次长,第三长路径. 然后在次dfs枚举求出切断某条边,求出这条边的两个端点为子 ...

  7. hdu 4679 Terrorist’s destroy 树的直径+dp

    题意:给你一棵树,每条边都有值W,然后问你去掉一条边,令val = w*max(两颗新树的直径),求val最小值~ 做法,先求树的直径,然后算出直径上每个点的最长枝条长度.这样对于每一条边,假如是枝条 ...

  8. hdu 4607 Park Visit 求树的直径

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n) ...

  9. 【HDU 4612 Warm up】BCC 树的直径

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...

随机推荐

  1. css3 媒体查询的学习。

    1.什么是媒体查询 媒体查询可以让我们根据设备显示器的特性(如视口宽度.屏幕比例.设备方向:横向或纵向)为其设定CSS样式,媒体查询由媒体类型和一个或多个检测媒体特性的条件表达式组成.媒体查询中可用于 ...

  2. python pycharm2018开启debug模式

    为什么需要开启DEBUG模式1.如果开启了DEBUG模式,那么在代码中如果抛出了异常,在浏览器的页面中可以看到具体的错误信息,以及具体的错误代码位置,方便开发者调试.2.如果开启DEBUG模式,那么以 ...

  3. C语言字符篇(一)字符串转换函数

      #include <stdlib.h>   double atof(const char *nptr);  将字符串转换成双精度浮点数 int atoi(const char *npt ...

  4. c++ tie,ignore

    ignore 一个未指定的类型对象,任何值都可以没有影响地赋值给它.通常使用tie来解压一个元组,作为可以忽略的占位符. #include <iostream> #include < ...

  5. PHP代码审计3-SQL注入,CSRF,动态函数执行与匿名函数执行,unserialize 反序列化漏洞,变量覆盖,文件管理,文件上传

    SQL注入 审计语句 [输入参数] SELECT,DELETE,UPDATE,INSERT 防御 转义: 1.开启gpc:判断解析用户提示的数据 2.mysql_real_escape_string( ...

  6. Best Practices in JavaScript

    Some items you should konw : Graceful degradation : ensuring that your web pages still work without ...

  7. 设置MySQL允许外网访问 费元星 feiyuanxing.com 站长

    1.修改配置文件sudo vim /etc/mysql/my.cnf把bind-address参数的值改成你的内/外网IP或0.0.0.0,或者直接注释掉这行. 2.登录数据库mysql -u roo ...

  8. shell脚本递归删除空文件夹

    有时我们需要递归删除空文件夹,网上找了一下,没有发现比较好的脚本,于是自己动手写了一个 脚本 #!/bin/bash # author: 十年后的卢哥哥(http://www.cnblogs.com/ ...

  9. hnust py road

    问题 C: Py Road 时间限制: 1 Sec  内存限制: 128 MB提交: 125  解决: 34[提交][状态][讨论版] 题目描述 Life is short,you need Pyth ...

  10. C#共享内存

    百度:C#共享内存. 文章:C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 资料:UnmanagedMemoryAccessor 资料:MemoryMappe ...