题意:

      给你一棵树,让你改变一条边,改变之后依然是一棵树,然后问你怎样改变才能让树的直径最短。这里的改变一条边指的是指把一条边长度不变,连在别的两个点上。

思路:

      首先求出树的直径,把直径上的边记录下来,然后在枚举这些边(枚举别的边没意义)每次枚举我的做法是后建造两棵树,我们只要在这两棵树之间连接一条边就行了,但是怎么连接呢? 我是先没别求两棵树的直径,然后在找到直径上中间点,然后连接这两棵树的中间点,只有这样才能保证最短,每次连接后的直径就是 两棵树的直径,和当前枚举的边长度+两个树被中间点分开的较长的那一个值的和,他们三个中较长的哪一个,就这样在所有中找到一个最小的就是答案。


#include<stdio.h>
#include<string.h>
#include<queue>
#include<map> #define N_node 2500 + 5
#define N_edge 5000 + 5
#define INF 1000000000

using namespace
std; typedef struct
{
int
to ,next ,cost;
}
STAR; typedef struct
{
int
a ,b ,c;
}
EDGE; STAR E[N_edge];
EDGE edge[N_node];
int
list[N_node] ,tot;
int
s_x[N_node] ,mer[N_node];
map<int ,map<int ,int> >hash; void add(int a ,int b ,int c)
{

E[++tot].to = b;
E[tot].cost = c;
E[tot].next = list[a];
list[a] = tot; E[++tot].to = a;
E[tot].cost = c;
E[tot].next = list[b];
list[b] = tot;
} void
Spfa(int s ,int n)
{
for(int
i = 0 ;i <= n ;i ++)
s_x[i] = INF ,mer[i] = i;
int
mark[N_node] = {0};
s_x[s] = 0 ,mark[s] = 1;
queue<int>q;
q.push(s);
while(!
q.empty())
{
int
xin ,tou;
tou = q.front();
q.pop();
mark[tou] = 0;
for(int
k = list[tou] ;k ;k = E[k].next)
{

xin = E[k].to;
if(
s_x[xin] > s_x[tou] + E[k].cost)
{

s_x[xin] = s_x[tou] + E[k].cost;
mer[xin] = tou;
if(!
mark[xin])
{

mark[xin] = 1;
q.push(xin);
}
}
}
}
return ;
} int
abss(int x)
{
return
x > 0 ? x : -x;
} int
maxx(int x ,int y)
{
return
x > y ? x : y;
} int main ()
{
int
t ,n ,a ,b ,c ,i ,j;
int
cas = 1;
scanf("%d" ,&t);
while(
t--)
{

scanf("%d" ,&n);
memset(list ,0 ,sizeof(list));
tot = 1;
for(
i = 1 ;i < n ;i ++)
{

scanf("%d %d %d" ,&edge[i].a ,&edge[i].b ,&edge[i].c);
edge[i].a ++ ,edge[i].b ++;
add(edge[i].a ,edge[i].b ,edge[i].c);
} int
p01 ,p02;
Spfa(1 ,n);
int
maxxx = -1;
for(
j = 1 ;j <= n ;j ++)
if(
maxxx < s_x[j] && s_x[j] != INF)
{

maxxx = s_x[j];
p01 = j;
}

Spfa(p01 ,n);
maxxx = -1;
for(
j = 1 ;j <= n ;j ++)
if(
maxxx < s_x[j] && s_x[j] != INF)
{

maxxx = s_x[j];
p02 = j;
}
int
x = p02;
hash.clear();
while(
x != mer[x])
{

hash[x][mer[x]] = hash[mer[x]][x] = 1;
x = mer[x];
} int
ans = INF;
for(
i = 1 ;i < n ;i ++)
{
if(!
hash[edge[i].a][edge[i].b]) continue;
memset(list ,0 ,sizeof(list)) ,tot = 1;
for(
j = 1 ;j < n ;j ++)
if(
j == i) continue;
else
add(edge[j].a ,edge[j].b ,edge[j].c); int p11 ,p12 ,mid1 ,l1 ,mid1l;
Spfa(edge[i].a ,n);
int
max = -1;
for(
j = 1 ;j <= n ;j ++)
if(
max < s_x[j] && s_x[j] != INF)
{

max = s_x[j];
p11 = j;
}

Spfa(p11 ,n);
max = -1;
for(
j = 1 ;j <= n ;j ++)
if(
max < s_x[j] && s_x[j] != INF)
{

max = s_x[j];
p12 = j;
}

l1 = max;
int
x = p12;
int
min = INF;
while(
x != mer[x])
{
if(
min > abss(s_x[x] - (l1 - s_x[x])))
{

min = abss(s_x[x] - (l1 - s_x[x]));
mid1 = x;
mid1l = maxx(s_x[x] ,l1 - s_x[x]);
}

x = mer[x];
}
if(
min > abss(s_x[x] - (l1 - s_x[x])))
{

min = abss(s_x[x] - (l1 - s_x[x]));
mid1 = x;
mid1l = maxx(s_x[x] ,l1 - s_x[x]);
} int
p21 ,p22 ,mid2 ,l2 ,mid2l;
Spfa(edge[i].b ,n);
max = -1;
for(
j = 1 ;j <= n ;j ++)
if(
max < s_x[j] && s_x[j] != INF)
{

max = s_x[j];
p21 = j;
}

Spfa(p21 ,n);
max = -1;
for(
j = 1 ;j <= n ;j ++)
if(
max < s_x[j] && s_x[j] != INF)
{

max = s_x[j];
p22 = j;
}

l2 = max;
x = p22;
min = INF;
while(
x != mer[x])
{
if(
min > abss(s_x[x] - (l2 - s_x[x])))
{

min = abss(s_x[x] - (l2 - s_x[x]));
mid2 = x;
mid2l = maxx(s_x[x] ,l2 - s_x[x]);
}

x = mer[x];
}
if(
min > abss(s_x[x] - (l2 - s_x[x])))
{

min = abss(s_x[x] - (l2 - s_x[x]));
mid2 = x;
mid2l = maxx(s_x[x] ,l2 - s_x[x]);
} int
now = maxx(maxx(l1 ,l2) ,edge[i].c + mid1l + mid2l);
if(
ans > now) ans = now;
}

printf("Case %d: %d\n" ,cas ++ ,ans);
}
return
0;
}

hdu 3721 树的最小直径的更多相关文章

  1. hdu 3721 树的直径

    思路:枚举+树的直径 #include<iostream> #include<cstring> #include<cstdio> #include<algor ...

  2. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

  3. HDU 1954 Subway tree systems (树的最小表示法)

    题意:用一个字符串表示树,0代表向下走,1代表往回走,求两棵树是否同构. 分析:同构的树经过最小表示会转化成两个相等的串. 方法:递归寻找每一棵子树,将根节点相同的子树的字符串按字典序排列,递归回去即 ...

  4. HDU 4607 Park Visit 树的最大直径

    题意: 莱克尔和她的朋友到公园玩,公园很大也很漂亮.公园包含n个景点通过n-1条边相连.克莱尔太累了,所以不能去参观所有点景点. 经过深思熟虑,她决定只访问其中的k个景点.她拿出地图发现所有景点的入口 ...

  5. hdu 4612 无向图连通分量缩点,然后求树的最大直径

    #pragma comment(linker,"/STACK:102400000,102400000") #include <iostream> #include &l ...

  6. Warm up HDU - 4612 树的直径

    题意:给出n个点和m条边的无向图,存在重边,问加一条边以后,剩下的桥的数量最少为多少. 题解: 你把这个无向图缩点后会得到一个只由桥来连接的图(可以说这个图中的所有边都是桥,相当于一棵树),然后我们只 ...

  7. bzoj2180: 最小直径生成树

    Description 输入一个无向图G=(V,E),W(a,b)表示边(a,b)之间的长度,求一棵生成树T,使得T的直径最小.树的直径即树的最长链,即树上距离最远的两点之间路径长度. Input 输 ...

  8. hdu 5274 树链剖分

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  9. 【学习笔记】最小直径生成树(MDST)

    简介 无向图中某一点(可以在顶点上或边上),这个点到所有点的最短距离的最大值最小,那么这个点就是 图的绝对中心. 无向图所有生成树中,直径最小的一个,被称为 最小直径生成树. 图的绝对中心的求法 下文 ...

随机推荐

  1. 解读KMP算法

    前后断断续续搞了5个月,每次都以为自己懂了, 但是要写的时候都不知从何下手,然后又是各种找博客,看帖子,所以这次试着用自己的语言写一个博客. 首先,KMP算法就是从一个模板字符串(S) 中匹配目标字符 ...

  2. POJ-2195(最小费用最大流+MCMF算法)

    Going Home POJ-2195 这题使用的是最小费用流的模板. 建模的时候我的方法出现错误,导致出现WA,根据网上的建图方法没错. 这里的建图方法是每次到相邻点的最大容量为INF,而花费为1, ...

  3. Selenium 4.0beta: Grid 工作原理

    Selenium 4.0 beta版已经发布,那么距离正式版已经不远了,在Selenium 4.0中变化比较大的就是Grid了,本文翻译了官方文档,重点介绍Grid 4的工作原理 Selenium G ...

  4. iot漏洞入门

    路由器漏洞入门 下载项目https://github.com/praetorian-inc/DVRF 安装quem sudo apt install qemu-user-static 安装gdb-mu ...

  5. FreeBSD安装xorg + xfce 4

    FreeBSD安装xorg,以及xfce 安装xorg 可选包 -xorg 完整xorg环境包 -xorg-minimal xorg最小化包 ports安装 cd /usr/ports/x11/xor ...

  6. C# 应用 - 封装类访问 Mysql 数据库

    个人经历的项目主要都是用 Postgresql 或 Oracle 数据库,本文非原创,从他处整理而来. 1. 库类 mysql.data.dll using MySql.Data.MySqlClien ...

  7. elementUI实现日期框选中项文本高亮

    { margin: 0; font: 12px "Helvetica Neue" } p.p2 { margin: 0; font: 12px "PingFang SC& ...

  8. Intellij IDEA实用插件Lombok

    使用@Data注解后 可以不用给属性添加get.set方法也可以使用get.set方法,但是必须添加lombok Plugin插件 1 打开设置Setting,选中Plugins,搜索并安装Lombo ...

  9. python基础学习之类的属性 增删改查

    类中的属性如何在类外部使用代码进行增删改查呢 增加.改变: setattr内置函数以及 __setattr__魔法方法 class A: aaa = '疏楼龙宿' a = A() setattr(a, ...

  10. 新的颜色对比度算法-感知对比度算法APCA

    目录 对比度 在控制台查看 插件或网站 感知对比度算法(APCA) APCA Math 原理 js 实现的 SAPC 最后 灵感的源泉来源于不断的接受新鲜事物. Chrome 89 新功能一览,性能提 ...