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

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

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

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <queue>
  6 #include <algorithm>
  7 using namespace std;
  8 #define INF 1000000
  9 struct node
 10 {
 11     int u,v,w,next,id;
 12 } edge[200000];
 13 int t,n,first[200001],flag[200001];
 14 int d[100001],in[100001],pre[100001];
 15 int pre1[100001];
 16 int pre2[100001];
 17 int sp1[100001];
 18 int sp2[100001];
 19 int sp3[100001];
 20 int sp4[100001];
 21 int dp[200001];
 22 int qu[100001];
 23 int qv[100001];
 24 int qw[100001];
 25 void CL()
 26 {
 27     int i;
 28     for(i = 0; i <= n; i ++)
 29     {
 30         first[i] = -1;
 31         flag[i] = 0;
 32         dp[i] = 0;
 33     }
 34     t = 1;
 35 }
 36 void add(int u,int v,int w,int id)
 37 {
 38     edge[t].u = u;
 39     edge[t].v = v;
 40     edge[t].w = w;
 41     edge[t].next = first[u];
 42     edge[t].id = id;
 43     first[u] = t ++;
 44 }
 45 void dfs(int x)
 46 {
 47     int i,maxz,v;
 48     in[x] = 1;
 49     maxz = 0;
 50     for(i = first[x]; i != -1; i = edge[i].next)
 51     {
 52         v = edge[i].v;
 53         if(flag[v]||in[v]) continue;
 54         in[v] = 1;
 55         dfs(v);
 56         maxz =  dp[v] + 1;
 57     }
 58     dp[x] = maxz;
 59     return;
 60 }
 61 int spfa(int x)
 62 {
 63     int u,v,i;
 64     for(i = 1; i <= n; i ++)
 65     {
 66         d[i] = -INF;
 67         pre[i] = -1;
 68         in[i] = 0;
 69     }
 70     queue<int>que;
 71     que.push(x);
 72     in[x] = 1;
 73     d[x] = 0;
 74     while(!que.empty())
 75     {
 76         u = que.front();
 77         que.pop();
 78         for(i = first[u]; i != -1; i = edge[i].next)
 79         {
 80             v = edge[i].v;
 81             if(in[v]) continue;
 82             if(d[v] < d[u] + 1)
 83             {
 84                 d[v] = d[u] + 1;
 85                 pre[v] = u;
 86                 pre1[v] = i;
 87                 in[v] = 1;
 88                 que.push(v);
 89             }
 90         }
 91     }
 92     int id,maxz = 0;
 93     for(i = 1; i <= n; i ++)
 94     {
 95         if(maxz < d[i])
 96         {
 97             maxz = d[i];
 98             id = i;
 99         }
100     }
101     return id;
102 }
103 int main()
104 {
105     int cas,i,u,v,w,a,b,tmax,bb,aa,sn = 1;
106     scanf("%d",&cas);
107     while(cas--)
108     {
109         scanf("%d",&n);
110         CL();
111         for(i = 1; i < n; i ++)
112         {
113             scanf("%d%d%d",&u,&v,&w);
114             add(u,v,w,i);
115             add(v,u,w,i);
116             qu[i] = u;
117             qv[i] = v;
118             qw[i] = w;
119         }
120         b = spfa(a = spfa(1));
121         bb = b;
122         aa = a;
123         tmax = d[b];
124         while(b != a)
125         {
126             flag[b] = 1;
127             pre2[pre[b]] = b;
128             b = pre[b];
129         }
130         flag[a] = 1;
131         for(i = 1; i <= n; i ++)
132             in[i] = 0;
133         for(i = 1; i <= n; i ++)
134         {
135             if(flag[i]||in[i])
136             {
137                 dfs(i);
138             }
139         }
140         int minz = INF,num,res = -1;
141         b = bb;
142         num = 0;
143         while(1)
144         {
145             sp1[b] = dp[b]+tmax - num;
146             sp2[b] = num + dp[b];
147             num ++;
148             if(a == b) break;
149             b = pre[b];
150         }
151         int pos = 0;
152         b = bb;
153         a = aa;
154         while(b != a)
155         {
156             sp2[pre[b]] = max(pos,sp2[pre[b]]);
157             pos = sp2[pre[b]];
158             b = pre[b];
159         }
160         b = bb;
161         a = aa;
162         pos = 0;
163         while(a != b)
164         {
165             sp1[pre2[a]] = max(pos,sp1[pre2[a]]);
166             pos = sp1[pre2[a]];
167             a = pre2[a];
168         }
169         b = bb;
170         a = aa;
171         for(i = 1; i < n; i ++)
172         {
173             if(flag[qu[i]]&&flag[qv[i]])
174             {
175                 if(pre[qu[i]] == qv[i])
176                 {
177                     u = qu[i];
178                     v = qv[i];
179                 }
180                 else
181                 {
182                     u = qv[i];
183                     v = qu[i];
184                 }
185                 int tt = qw[i]*(max(sp1[v],sp2[u]));
186                 if(minz > tt)
187                 {
188                     minz = tt;
189                     res = i;
190                 }
191                 else if(minz == tt)
192                 {
193                     res = min(res,i);
194                 }
195             }
196             else
197             {
198                 if(minz > qw[i]*tmax)
199                 {
200                     minz = qw[i]*tmax;
201                     res = i;
202                 }
203                 else if(minz == qw[i]*tmax)
204                 {
205                     res = min(res,i);
206                 }
207             }
208         }
209         printf("Case #%d: %d\n",sn++,res);
210     }
211     return 0;
212 }

转载于:https://www.cnblogs.com/naix-x/p/3260375.html

HDU 4679 Terrorist’s destroy相关推荐

  1. hdu 4679 树状dp

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

  2. hdu 4679 树的直径

    1 /* 2 题目大意:给n个点n-1条边的树,求删除哪条边时两个树中最大的直径与边权的乘积最小. 3 树的直径(Diameter)是指树上的最长简单路. 4 直径的求法:两遍BFS (or DFS) ...

  3. 【 2013 Multi-University Training Contest 8 】

    HDU 4678 Mine 对于每个空白区域,求SG值. 最后异或起来等于0,先手必败. 1 #pragma comment(linker,"/STACK:102400000,1024000 ...

  4. python能以文本和二进制方式处理文件_Python文件处理之文件写入方式与写缓存(三)...

    Python的open的写入方式有: write(str):将str写入文件 writelines(sequence of strings):写多行到文件,参数为可迭代对象 首先来看下writelin ...

  5. HDU 6089 Rikka with Terrorist (线段树)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6089 题解 这波强行维护搞得我很懵逼... 扫描线,只考虑每个点能走到左上方(不包括正上方,但包括正左 ...

  6. 【HDU - 6187】Destroy Walls(思维,最大生成树)

    题干: Long times ago, there are beautiful historic walls in the city. These walls divide the city into ...

  7. HDU 6187 Destroy Walls

    Destroy Walls Long times ago, there are beautiful historic walls in the city. These walls divide the ...

  8. HDU 4940 Destroy Transportation system(无源汇上下界网络流)

    Problem Description Tom is a commander, his task is destroying his enemy's transportation system. Le ...

  9. I - Destroy Walls (HDU - 6187)

    - 题目大意 有一个V个结点M条边的带边权无向平面图,有一个人在一个区域,要拆一些墙使得他可以到达任意一个区域,问最小花费. - 解题思路 先开始想不通,看了别人突然恍然大悟,根据欧拉公式我们可以知道 ...

最新文章

  1. C++ 中this指针的用途
  2. 修改新版am335x支持1G主频的方法[来自A Xian调试记录]
  3. java如何让控制台不输出报错_Java 控制台输入输出操作记录
  4. cropped-img_2692.jpg
  5. python 字符串格式化,使用f前缀
  6. Java代码中常见技术债务处理之Exception
  7. 云原生架构下的持续交付实践
  8. 代码实现tan graph model for classification_自定义 Estimator 实现(以BERT为例)
  9. 938. 二叉搜索树的范围和
  10. java名字自动生成_Java名字生成器
  11. matlab 对称矩阵特征值为负数,MATLAB中对称矩阵的复特征向量
  12. 如何删除“无法删除文件,无法读取源文件或磁盘”文件
  13. Vue源码分析系列:目录
  14. 举个栗子!Tableau 技巧(86):用 ZN 函数处理数据缺失点
  15. vue组件开发之仿CSDN发布博客时面包屑标签和checkbox选中效果
  16. Flash和JS实现的图片幻灯片切换特效
  17. 积木式编程——自制app点灯
  18. 国产手机已经用上了 120W 快充技术,苹果还在用20W的原因一
  19. centOS6添加开机启动
  20. [附源码]计算机毕业设计JAVA汽车租赁系统

热门文章

  1. 创建窗口,输入一个无符号整数,输出其对应的二进制数
  2. php+ajax+打开新页面跳转,ajax怎样跳转到新的jsp页面(附代码)
  3. linux 安装 yum etcd,安装etcd - Go语言中文网 - Golang中文社区
  4. ehcache缓存原理_Mybatis-09-缓存
  5. 目标检测综述——单阶段检测器
  6. 阿里巴巴开源AI技术:强化学习在阿里的技术演进与业务创新
  7. 2019工作榜单|Python程序员吸金榜,AI排第一,这个我服!
  8. 特征工程(三):特征缩放,从词袋到 TF-IDF
  9. mysql 大文件导入工具_BigDump:导入超大mysql数据库文件工具
  10. Ubuntu 配置Samba 服务器