HDU 3721 - Building Roads(DFS`树的直径)
来源:互联网 发布:龙腾管家软件下载 编辑:程序博客网 时间:2024/05/16 04:02
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=3721
题意:
n个点的有边权的树,移动一条边(即改变边的两个端点),使得树的直径最短。
思路:
移动的边在原树的直径上,移动后原树变成两棵子树,求出两棵子树的直径。
枚举子树直径上的点,决定移动边的两个端点,求出最小的距离。
AC.
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 2505;int tot, head[maxn];struct Edge{ int to, w, next;}edge[maxn*2];void init(){ tot = 0; memset(head, -1, sizeof(head));}void addedge(int u, int v, int w){ edge[tot].to = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++;}int num[maxn];int res, point;void dfs(int u, int fa){ for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to, w = edge[i].w; if(v == fa) continue; num[v] = num[u] + w; if(res < num[v]) { res = num[v]; point = v; } dfs(v, u); }}struct Path{ int to, id;}path[maxn];void dfs1(int u, int fa){ for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to, w = edge[i].w; if(v == fa) continue; num[v] = num[u] + w; path[v].to = u; path[v].id = i; if(res < num[v]) { res = num[v]; point = v; } dfs1(v, u); }}int now;int smpath[maxn];int nog1, nog2;void dfsmall(int u, int fa){ if(u == now) return; for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to, w = edge[i].w; if(nog1 == i || nog2 == i) continue; if(v == fa) continue; num[v] = num[u] + w; if(res < num[v]) { res = num[v]; point = v; } dfsmall(v, u); }}void dfsmall2(int u, int fa){ for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to, w = edge[i].w; if(nog1 == i || nog2 == i) continue; if(v == fa) continue; num[v] = num[u] + w; smpath[v] = u; if(res < num[v]) { res = num[v]; point = v; } dfsmall2(v, u); }}void initdfs(){ res = 0; memset(num, 0, sizeof(num));}int main(){ // freopen("in", "r", stdin); int TT, ca = 1; scanf("%d", &TT); while(TT--) { int n; scanf("%d", &n); init(); int u, v, w; for(int i = 1; i < n; ++i) { scanf("%d%d%d", &u, &v, &w); addedge(u, v, w); addedge(v, u, w); } memset(path, -1, sizeof(path)); int S, T; initdfs(); dfs(1, 1); S = point; initdfs(); dfs1(S, S); T = point; //printf("%d, %d\n", S, T); int ans = inf, r; int s1, t1, s2, t2, p1, p2; for(int i = T; ~i; i = path[i].to) { int id = path[i].id; if(id == -1) break; int u = edge[id].to, v = edge[id^1].to; nog1 = id; nog2 = id^1; r = edge[id].w; memset(smpath, -1, sizeof(smpath)); initdfs(); dfsmall(u, u); s1 = point; initdfs(); dfsmall2(s1, s1); t1 = point; int r1 = num[t1]; // printf("****(%d, %d) = %d\n", s1, t1, num[t1]); int tmp = inf; for(int j = t1; ~j; j = smpath[j]) { int cnt = max(num[t1]-num[j], num[j]); tmp = min(tmp, cnt); } // printf("half path = %d\n", tmp); r += tmp; memset(smpath, -1, sizeof(smpath)); initdfs(); dfsmall(v, v); s2 = point; initdfs(); dfsmall2(s2, s2); t2 = point; int r2 = num[t2]; // printf("****(%d, %d) = %d\n", s2, t2, num[t2]); tmp = inf; for(int j = t2; ~j; j = smpath[j]) { int cnt = max(num[t2]-num[j], num[j]); tmp = min(tmp, cnt); } // printf("half path = %d\n", tmp); r += tmp; //printf("(%d, %d) = %d\n\n", u, v, r); r = max(r, max(r1, r2)); ans = min(ans, r); } printf("Case %d: %d\n", ca++, ans); } return 0;}
0 0
- HDU 3721 - Building Roads(DFS`树的直径)
- hdu 3721 Building Roads 树的直径
- HDU 3721 Building Roads 树形dp + 枚举直径
- HDU 3721 Building Roads
- HDU 3721 Building Roads
- hdu 3721 树的直径
- HDU 3534 Tree(dfs统计树的直径的数量)
- hdu 4514 dfs判断环 及 求树的直径
- hdu 3721 uvalive 5026 building roads
- 【树形DP】 HDU 3721 Building Roads
- 树形dp-hdu-3721-Building Roads
- Roads in the North 【树的直径】
- hdu 2631 Roads in the North【树的直径+前向星存图】
- Codeforces Round #427 (Div. 2) F-Roads in the Kingdom (树的直径,DFS+DP思想)
- hdu 3721 树的最小直径
- 3124: [Sdoi2013]直径【dfs】【树的直径】【外向树】
- 2017.10.12. DFS求树的直径
- poj bfs/dfs求树直径相关之2361 Roads in the North
- html5 storage
- PHP CLI模式下的多进程应用
- Java中判断字符串是否为数字的五种方法
- c++ 读写Excel及数据导入SQLServer
- C语言及程序设计.第二十三课.项目6.前导0的数字
- HDU 3721 - Building Roads(DFS`树的直径)
- STL remove和erase
- AndroidUI 视图动画-缩放动画效果 (ScaleAnimation)
- SCU 4437 Carries 想法题
- 读取数量不定的输入数据
- Android 事件处理详解(三) —— 响应系统设置的事件[Configuration]
- DirectX11 山峰与河谷示例Demo
- CSS表格
- 黑马程序员——面向对象之异常(一)