HDU 4679 Terrorist’s destroy
如果不在最长路的边,那么肯定是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相关推荐
- hdu 4679 树状dp
思路:我们其实只需要枚举每条边,求得最小值就行了. 先dfs算出每个节点作为根时,其子树的最长路径,以及进过该节点的最长,次长,第三长路径. 然后在次dfs枚举求出切断某条边,求出这条边的两个端点为子 ...
- hdu 4679 树的直径
1 /* 2 题目大意:给n个点n-1条边的树,求删除哪条边时两个树中最大的直径与边权的乘积最小. 3 树的直径(Diameter)是指树上的最长简单路. 4 直径的求法:两遍BFS (or DFS) ...
- 【 2013 Multi-University Training Contest 8 】
HDU 4678 Mine 对于每个空白区域,求SG值. 最后异或起来等于0,先手必败. 1 #pragma comment(linker,"/STACK:102400000,1024000 ...
- python能以文本和二进制方式处理文件_Python文件处理之文件写入方式与写缓存(三)...
Python的open的写入方式有: write(str):将str写入文件 writelines(sequence of strings):写多行到文件,参数为可迭代对象 首先来看下writelin ...
- HDU 6089 Rikka with Terrorist (线段树)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6089 题解 这波强行维护搞得我很懵逼... 扫描线,只考虑每个点能走到左上方(不包括正上方,但包括正左 ...
- 【HDU - 6187】Destroy Walls(思维,最大生成树)
题干: Long times ago, there are beautiful historic walls in the city. These walls divide the city into ...
- HDU 6187 Destroy Walls
Destroy Walls Long times ago, there are beautiful historic walls in the city. These walls divide the ...
- HDU 4940 Destroy Transportation system(无源汇上下界网络流)
Problem Description Tom is a commander, his task is destroying his enemy's transportation system. Le ...
- I - Destroy Walls (HDU - 6187)
- 题目大意 有一个V个结点M条边的带边权无向平面图,有一个人在一个区域,要拆一些墙使得他可以到达任意一个区域,问最小花费. - 解题思路 先开始想不通,看了别人突然恍然大悟,根据欧拉公式我们可以知道 ...
最新文章
- C++ 中this指针的用途
- 修改新版am335x支持1G主频的方法[来自A Xian调试记录]
- java如何让控制台不输出报错_Java 控制台输入输出操作记录
- cropped-img_2692.jpg
- python 字符串格式化,使用f前缀
- Java代码中常见技术债务处理之Exception
- 云原生架构下的持续交付实践
- 代码实现tan graph model for classification_自定义 Estimator 实现(以BERT为例)
- 938. 二叉搜索树的范围和
- java名字自动生成_Java名字生成器
- matlab 对称矩阵特征值为负数,MATLAB中对称矩阵的复特征向量
- 如何删除“无法删除文件,无法读取源文件或磁盘”文件
- Vue源码分析系列:目录
- 举个栗子!Tableau 技巧(86):用 ZN 函数处理数据缺失点
- vue组件开发之仿CSDN发布博客时面包屑标签和checkbox选中效果
- Flash和JS实现的图片幻灯片切换特效
- 积木式编程——自制app点灯
- 国产手机已经用上了 120W 快充技术,苹果还在用20W的原因一
- centOS6添加开机启动
- [附源码]计算机毕业设计JAVA汽车租赁系统
热门文章
- 创建窗口,输入一个无符号整数,输出其对应的二进制数
- php+ajax+打开新页面跳转,ajax怎样跳转到新的jsp页面(附代码)
- linux 安装 yum etcd,安装etcd - Go语言中文网 - Golang中文社区
- ehcache缓存原理_Mybatis-09-缓存
- 目标检测综述——单阶段检测器
- 阿里巴巴开源AI技术:强化学习在阿里的技术演进与业务创新
- 2019工作榜单|Python程序员吸金榜,AI排第一,这个我服!
- 特征工程(三):特征缩放,从词袋到 TF-IDF
- mysql 大文件导入工具_BigDump:导入超大mysql数据库文件工具
- Ubuntu 配置Samba 服务器