HDU 4679 Terrorist’s destroy
如果不在最长路的边,那么肯定是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的更多相关文章
- 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 ...
- hdu 4679 Terrorist’s destroy 树形DP
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679 题意:给定一颗树,每条边有一个权值w,问切掉哪条边之后,分成的两颗树的较大的直径*切掉边的权值最小? ...
- hdu 4679 Terrorist’s destroy 树的直径+dp
题意:给你一棵树,每条边都有值W,然后问你去掉一条边,令val = w*max(两颗新树的直径),求val最小值~ 做法,先求树的直径,然后算出直径上每个点的最长枝条长度.这样对于每一条边,假如是枝条 ...
- 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 ...
- 树形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 ...
- HDU-4679 Terrorist’s destroy 树形DP,维护
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679 题意:给一颗树,每个边有一个权值,要你去掉一条边权值w剩下的两颗子树中分别的最长链a,b,使得w ...
- hdu 4679 树状dp
思路:我们其实只需要枚举每条边,求得最小值就行了. 先dfs算出每个节点作为根时,其子树的最长路径,以及进过该节点的最长,次长,第三长路径. 然后在次dfs枚举求出切断某条边,求出这条边的两个端点为子 ...
- hdu 4679 (树形DP)
题意:给一棵树,边的权值都是1,摧毁每条边是有代价的,选择摧毁一条边,把一棵树分成两部分,求出两部分中距离最大的两点的距离,求出距离*代价最小的边,多条的话输出序号最小的. 刚开始理解错题意了,wro ...
- HDU 4679 String
String Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Sub ...
随机推荐
- overflow-x和overflow-y其中一个设置为visible时的奇怪现象
当overflow-x和overflow-y其中一个设置为visible时,如果另一个不是visible,那么它会被自动重置为auto 看看效果先: 第一次遇到这个问题时,我还以为是chrome的一个 ...
- android.os.BadParcelableException: ClassNotFoundException when unmarshalling:解决办法
例如在用AlarmManager的时候 AlarmManager alarmMgr = (AlarmManager) mContext .getSystemService(Context.ALARM_ ...
- call_user_func_array使用原型
If you need to call object and class methods in PHP < 4.0.4, the following code ought to do the t ...
- 【SpringMVC】SpringMVC系列2之@RequestMapping 映射约束请求
@RequestMapping 映射约束请求 2.1.映射请求URL Spring MVC 使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求,在控制器的类定义及方法定义 ...
- IIS安装时,添加/编辑应用程序扩展名映射 确定按钮不可用。
原因是:执行文件的路径太长,需要激活按钮. 方法一:选择较短路径的执行文件,先激活按钮. 方法二:点击该路径,就可以激活确认按钮了.
- 获取Assets目录下的图片显示并上传
package com.jingle.getlocal; import java.io.ByteArrayOutputStream; import java.io.InputStream; impor ...
- Codeforces Round #321 (Div. 2)C(tree dfs)
题意:给出一棵树,共有n个节点,其中根节点是Kefa的家,叶子是restaurant,a[i]....a[n]表示i节点是否有猫,问:Kefa要去restaurant并且不能连续经过m个有猫的节点有多 ...
- primace 5.0软件的Debug ware 功能的使用方法简介
用primace 软件已经一年多了,一直不知道Debug ware 软件怎么使用,上周终于逮住FAE请教了下这个功能的使用方法.发现这个功能和signalTap ii 原理不一样,这个是非时事的波形, ...
- Android文件Apk下载变ZIP压缩包解决方案
[root@ conf]# pwd /alidata/server/nginx/conf [root@ conf]# vi mime.types application/vnd.android.pac ...
- mongoDb学习以及spring管理
1.windows下的安装http://www.cnblogs.com/liuzhiying/p/5915741.html 2.慕课网学习单机操作mongoDb 赋权限:http://blog.csd ...