如果不在最长路的边,那么肯定是w*最长路。

如果在最长路,那么把最长路分成两段,左边树的最长路就是左段+左边点的次短路(不包含最长路上的点的最长路) ,右边同理。

还有就是更新,经过左端点的最长路,不一定是整颗左边树的最长路,乱搞一下就可以了。我是搞成一条链,写的很麻烦。。从一点搞到了快四点。。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
#define INF 1000000
struct node
{
int u,v,w,next,id;
} edge[];
int t,n,first[],flag[];
int d[],in[],pre[];
int pre1[];
int pre2[];
int sp1[];
int sp2[];
int sp3[];
int sp4[];
int dp[];
int qu[];
int qv[];
int qw[];
void CL()
{
int i;
for(i = ; i <= n; i ++)
{
first[i] = -;
flag[i] = ;
dp[i] = ;
}
t = ;
}
void add(int u,int v,int w,int id)
{
edge[t].u = u;
edge[t].v = v;
edge[t].w = w;
edge[t].next = first[u];
edge[t].id = id;
first[u] = t ++;
}
void dfs(int x)
{
int i,maxz,v;
in[x] = ;
maxz = ;
for(i = first[x]; i != -; i = edge[i].next)
{
v = edge[i].v;
if(flag[v]||in[v]) continue;
in[v] = ;
dfs(v);
maxz = dp[v] + ;
}
dp[x] = maxz;
return;
}
int spfa(int x)
{
int u,v,i;
for(i = ; i <= n; i ++)
{
d[i] = -INF;
pre[i] = -;
in[i] = ;
}
queue<int>que;
que.push(x);
in[x] = ;
d[x] = ;
while(!que.empty())
{
u = que.front();
que.pop();
for(i = first[u]; i != -; i = edge[i].next)
{
v = edge[i].v;
if(in[v]) continue;
if(d[v] < d[u] + )
{
d[v] = d[u] + ;
pre[v] = u;
pre1[v] = i;
in[v] = ;
que.push(v);
}
}
}
int id,maxz = ;
for(i = ; i <= n; i ++)
{
if(maxz < d[i])
{
maxz = d[i];
id = i;
}
}
return id;
}
int main()
{
int cas,i,u,v,w,a,b,tmax,bb,aa,sn = ;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
CL();
for(i = ; i < n; i ++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w,i);
add(v,u,w,i);
qu[i] = u;
qv[i] = v;
qw[i] = w;
}
b = spfa(a = spfa());
bb = b;
aa = a;
tmax = d[b];
while(b != a)
{
flag[b] = ;
pre2[pre[b]] = b;
b = pre[b];
}
flag[a] = ;
for(i = ; i <= n; i ++)
in[i] = ;
for(i = ; i <= n; i ++)
{
if(flag[i]||in[i])
{
dfs(i);
}
}
int minz = INF,num,res = -;
b = bb;
num = ;
while()
{
sp1[b] = dp[b]+tmax - num;
sp2[b] = num + dp[b];
num ++;
if(a == b) break;
b = pre[b];
}
int pos = ;
b = bb;
a = aa;
while(b != a)
{
sp2[pre[b]] = max(pos,sp2[pre[b]]);
pos = sp2[pre[b]];
b = pre[b];
}
b = bb;
a = aa;
pos = ;
while(a != b)
{
sp1[pre2[a]] = max(pos,sp1[pre2[a]]);
pos = sp1[pre2[a]];
a = pre2[a];
}
b = bb;
a = aa;
for(i = ; i < n; i ++)
{
if(flag[qu[i]]&&flag[qv[i]])
{
if(pre[qu[i]] == qv[i])
{
u = qu[i];
v = qv[i];
}
else
{
u = qv[i];
v = qu[i];
}
int tt = qw[i]*(max(sp1[v],sp2[u]));
if(minz > tt)
{
minz = tt;
res = i;
}
else if(minz == tt)
{
res = min(res,i);
}
}
else
{
if(minz > qw[i]*tmax)
{
minz = qw[i]*tmax;
res = i;
}
else if(minz == qw[i]*tmax)
{
res = min(res,i);
}
}
}
printf("Case #%d: %d\n",sn++,res);
}
return ;
}

HDU 4679 Terrorist’s destroy的更多相关文章

  1. HDU 4679 Terrorist’s destroy (2013多校8 1004题 树形DP)

    Terrorist’s destroy Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  2. hdu 4679 Terrorist’s destroy 树形DP

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679 题意:给定一颗树,每条边有一个权值w,问切掉哪条边之后,分成的两颗树的较大的直径*切掉边的权值最小? ...

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

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

  4. Terrorist’s destroy HDU - 4679

    Terrorist’s destroy HDU - 4679 There is a city which is built like a tree.A terrorist wants to destr ...

  5. 树形DP 2013多校8(Terrorist’s destroy HDU4679)

    题意: There is a city which is built like a tree.A terrorist wants to destroy the city's roads. But no ...

  6. HDU-4679 Terrorist’s destroy 树形DP,维护

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679 题意:给一颗树,每个边有一个权值,要你去掉一条边权值w剩下的两颗子树中分别的最长链a,b,使得w ...

  7. hdu 4679 树状dp

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

  8. hdu 4679 (树形DP)

    题意:给一棵树,边的权值都是1,摧毁每条边是有代价的,选择摧毁一条边,把一棵树分成两部分,求出两部分中距离最大的两点的距离,求出距离*代价最小的边,多条的话输出序号最小的. 刚开始理解错题意了,wro ...

  9. HDU 4679 String

    String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Sub ...

随机推荐

  1. Linux 怎么查看服务的启动进程所占用的目录

    lsof简介 lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以 ...

  2. 杭电hdoj题目分类

    HDOJ 题目分类 //分类不是绝对的 //"*" 表示好题,需要多次回味 //"?"表示结论是正确的,但还停留在模块阶 段,需要理解,证明. //简单题看到就 ...

  3. 07 DAY 1

    壮烈的一天... 第一题 本意是水题,然后写了块状数组模拟,最后发现算法错了... 然后其实快排一遍扫一遍完事... 100分 #include <cstdio> #include < ...

  4. encode与decode,unicode与中文乱码的问题

    encode是指将unicode字符编码成其他字符集的字符,如utf-8,ascii等: 而decode是指将其他字符编码,如utf-8转换成unicode编码. encode是指将人类用的语言(字符 ...

  5. MQTT——安装、测试

    MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用         http://blog.csdn.net/xukai871105/article/details/39252653 ...

  6. 30.赋值运算符重载函数[Assign copy constructor]

    [问题] 给出如下CMyString的声明,要求为该类型添加赋值运算符函数.  C++ Code  1234567891011   class CMyString { public:     CMyS ...

  7. ubuntu maven环境安装配置

    转载地址:http://my.oschina.net/hongdengyan/blog/150472#OSC_h1_4 一.环境说明: 操作系统:Ubuntu 12.04.2 LTS maven:ap ...

  8. 告别div,可以代替div的几个标签

    几个最常用的用来代替DIV的HTML5元素 虽说html5中大多数功能性的元素如<video><canvas><audio>等还得不到当前主流浏览器的支持(主要就是 ...

  9. 使用MySQL索引的几个问题

    1.索引不存储null值 更准确的说,单列索引不存储null值,复合索引不存储全为null的值.索引不能存储Null,所以对这列采用is null条件时,因为索引上根本 没Null值,不能利用到索引, ...

  10. C# 如何判断系统是否是静音

    推荐的方法,使用CoreAudioApi.dll,仅在win7上测试过: private MMDevice defaultDevice = null; //判断当前系统扬声器状态 private bo ...