题意:

给出一棵树,删除一条边再添加一条边,求新树的最短的直径。

分析:

因为n比较小(n ≤ 2500),所以可以枚举删除的边,分裂成两棵树,然后有这么一个结论:

合并两棵树后得到的新树的最短直径为:

这两棵树一定是这样合并的,分别取两棵树直径的中点,然后将其连接起来。这样新树的直径才是最短的。

所以在找直径的同时还要记录下路径,方便找到中点。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int maxn = + ; int n; struct Edge
{
int u, v, nxt;
bool del;
}; Edge edges[maxn * ];
int ecnt;
int head[maxn]; void AddEdge(int u, int v)
{
Edge& e = edges[ecnt];
e.u = u;
e.v = v;
e.nxt = head[u];
e.del = false;
head[u] = ecnt++;
} int pre[maxn];
int len, id;
void dfs(int u, int fa, int dep)
{
pre[u] = fa;
if(dep > len) { len = dep; id = u; }
for(int i = head[u]; ~i; i = edges[i].nxt)
{
if(edges[i].del) continue;
int v = edges[i].v;
if(v == fa) continue;
dfs(v, u, dep + );
}
} int mid; int diameter(int u)
{
id = u;
len = ;
dfs(u, , );
int s = id;
len = ;
dfs(s, , ); mid = id;
for(int i = ; i < len / ; i++) mid = pre[mid]; return len;
} int main()
{
int T; scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
memset(head, -, sizeof(head));
ecnt = ; for(int u, v, i = ; i < n; i++)
{
scanf("%d%d", &u, &v);
AddEdge(u, v); AddEdge(v, u);
} int ans = ;
int del_u, del_v, add_u, add_v; for(int i = ; i < ecnt; i += )
{
Edge& e = edges[i];
edges[i].del = true;
edges[i^].del = true; int d1 = diameter(e.u), tu = mid;
int d2 = diameter(e.v), tv = mid;
int d3 = (d1 + ) / + (d2 + ) / + ; d1 = max(max(d1, d2), d3);
if(d1 < ans)
{
ans = d1;
del_u = edges[i].u;
del_v = edges[i].v;
add_u = tu;
add_v = tv;
} edges[i].del = false;
edges[i^].del = false;
} printf("%d\n%d %d\n%d %d\n", ans, del_u, del_v, add_u, add_v);
} return ;
}

代码君

最新文章

  1. mac 安装mvn 失败
  2. cmd 导出目录树
  3. POJ 1743 (后缀数组 二分) Musical Theme
  4. Oracle用户进程跟踪
  5. android 中 ColorDrawable dw = new ColorDrawable(0x3ccccccc),关于颜色定义的总结
  6. java 修饰符之修饰范围
  7. SQLServer数据库维护(一)碎片检查整理
  8. ARE 212 - Problem Set 5
  9. python之找最后一个人
  10. 使用Visual Studio Team Services持续集成(四)——使用构建运行测试
  11. 使用newtonjson解决Json日期格式问题
  12. PyCharm选择性忽略PEP8代码风格警告信息
  13. B - 集合选数 (状压DP)
  14. JavaScrip(一)JavaScrip的写法
  15. android testview + listview 整体滚动刷新
  16. mysql用户管理与权限
  17. mysql概要(二)类型(数值型,字符型,时间类型
  18. Spring Data JPA(官方文档翻译)
  19. 微信小程序使用函数的三种方法
  20. Entity Framework 复杂类型(转)

热门文章

  1. SQL Server事务的四种隔离级别
  2. ajax取到数据后如何拿到data.data中的属性值
  3. BZOJ4299: Codechef FRBSUM(主席树)
  4. 22/tcp open|filtered ssh 80/tcp open|filtered http
  5. SharePoint Server和Office 365之间的混合模式集成概述
  6. jspscriptlet标签
  7. 编写C#程序,自动将bing首页图片设为壁纸
  8. 使 windows 无需输入开机密码自动进入系统
  9. alibaba druid监控页面的使用配置
  10. mina架构在JT/T808协议应用程序中的应用