/*
题目大意:给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. js如何获得系统时间年月日时分秒

    javascript 自带有个对象(构造函数),Date().下面是代码: 回答一: var now = new Date();  var nowTime = now.toLocaleString() ...

  2. Oracle创建表空间,添加用户及授权

    工具/原料 PLSQL 方法/步骤 1.在PLSQL里,用system/css(orcl系统用户)登陆,登陆的时候普通用户登陆选择normal就可以了   2.Oracle用户新增 执行语句 crea ...

  3. python之微信好友统计信息

    需要安装库:wxpy 代码如下: from wxpy import Bot,Tuling,embed,ensure_one bot = Bot(cache_path=True) #获取好友信息 bot ...

  4. mysql sum 为 0 的解决方法

    使用SQL语句SUM函数的时候,默认查询没有值的情况下返回的是null,而实际可能我们要用的是返回0. 解决方法:SELECT SUM(count) FROM test_table 改成: SELEC ...

  5. Fragment Touch事件泄露

    当Fragment的栈里面有几个fragment的时候,这个时候如果是几个fragment状态是hide,当你触摸当前fragment的时候,下层的fragment的事件被触发,这是由于Touch事件 ...

  6. TouTiao开源项目 分析笔记11 以总体到局部的思路 构建图片主列表

    1.构建图片主列表的整体片段PhotoTabLayout 1.1.首先创建一个PhotoTabLayout片段 public class PhotoTabLayout extends Fragment ...

  7. BZOJ 5004: 开锁魔法II

    比较显然 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; i ...

  8. HDU 5293 Tree chain problem 树形DP

    题意: 给出一棵\(n\)个节点的树和\(m\)条链,每条链有一个权值. 从中选出若干条链,两两不相交,并且使得权值之和最大. 分析: 题解 #include <cstdio> #incl ...

  9. The GNU C Library

    Any Unix-like operating system needs a C library: the library which defines the ``system calls'' and ...

  10. Lazarus教程 中文版后续给出

    市面上有介绍Delphi的书籍(近来Delphi的书也是越来越少了),但没有一本系统的介绍Lazarus的书,这本书是网上的仅有的一本Lazarus教程,目前全部是英文,不过我已经着手开始翻译,争取尽 ...