【HDU3721】枚举+最长路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3721
题意:给你一颗n个节点n-1条边的树,每条边都有一个权值,现在让你任意移动一条边然后把这条边连接到任意两个点上,最后问你怎样移动才能使树上相距最远的两个点距离最小。
思路:先求出树的最长路,然后枚举移动最长路上的所有边,移走这条边后,原树必定分为不连接的两颗子树,分别求这两颗子树的最长路,然后分别找到两颗子树最长路上靠近中点的点,把这两个点连上刚刚从母树移走的边,再求一遍母树最长路,比较所有结果取最优解即可。
注意每次枚举移动后都要把图复原然后继续枚举。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std; const int maxn=;
const int oo=0x3fffffff;
int visit[maxn], pre[*maxn];
int reach[*maxn], flow[*maxn], head[maxn], next[*maxn];
int stack[*maxn], sa[*maxn], sb[*maxn];
int color[*maxn];
int st, sd, ans, edge; struct Node
{
int u, e;
int dis;
};
queue<Node>q; inline void addedge(int u, int v, int c)
{
reach[edge]=v, flow[edge]=c, next[edge]=head[u], head[u]=edge++;
reach[edge]=u, flow[edge]=c, next[edge]=head[v], head[v]=edge++;
} void bfs(int ss,int op)
{
memset(visit,,sizeof(visit));
while(!q.empty()) q.pop();
Node s, p;
s.u=ss, s.dis=, s.e=-, sd=-, st=ss;
q.push(s);
visit[ss]=;
int maxx=, pos;
while(!q.empty())
{
p=q.front();
q.pop();
for(int i=head[p.u]; i>=; i=next[i])
{
if(color[i]||color[i^]) continue;
int v=reach[i], val=flow[i];
s.u=v, s.dis=p.dis+val, s.e=i;
if(!visit[s.u])
{
visit[s.u]=;
pre[s.e]=p.e;
if(s.dis>maxx)
{
st=s.u;
maxx=s.dis;
sd=s.e;
}
q.push(s);
}
}
}
++op;
if(op==) bfs(st,op);
else ans=maxx;
} int cal(int s[], int n, double len) ///找最靠近中点的点
{
int sum=;
for(int i=; i<n; i++)
{
sum+=flow[s[i]];
if(sum>=len)
{
if(sum-len<=len-(sum-flow[ s[i] ])) return reach[ s[i]^ ];
else return reach[ s[i] ];
}
}
} int Solve(int n)
{
int MIN=oo;
memset(color,,sizeof(color));
memset(pre,-,sizeof(pre));
bfs(,);
int top=;
while(sd!=-) stack[top++]=sd,sd=pre[sd];
for(int i=; i<top; i++) ///枚举最长路上的所有边
{
int x=stack[i], na=, nb=;
color[x]=;
for(int j=; j<edge; j++) pre[j]=-;
bfs(reach[x],);
while(sd!=-) sa[na++]=sd, sd=pre[sd];
int u=cal(sa,na,1.0*ans/);
if(!na) u=reach[x];
for(int j=; j<edge; j++) pre[j]=-;
bfs(reach[x^],);
while(sd!=-) sb[nb++]=sd, sd=pre[sd];
int v=cal(sb,nb,1.0*ans/);
if(!nb) v=reach[x^];
addedge(u,v,flow[x]);
bfs(,);
MIN=min(MIN,ans);
color[edge-]=; ///注意把新加的边移除,
color[x]=;
}
return MIN;
} int main()
{
int n, T, tcase=;
cin >> T;
while(T--)
{
cin >> n;
edge=;
memset(head,-,sizeof(head));
for(int i=; i<n; i++)
{
int a, b, c;
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
}
int tmp=Solve(n);
printf("Case %d: %d\n",++tcase,tmp);
}
}
/*
10
9
0 1 1
1 2 1
2 3 1
2 4 1
0 5 1
5 6 1
5 7 1
7 8 1
4
0 1 2
1 2 2
2 3 2
5
0 1 1
1 2 2
2 3 3
3 4 4
*/
【HDU3721】枚举+最长路的更多相关文章
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur (SCC缩点,SPFA最长路,枚举反边)
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- zoj 3088 Easter Holidays(最长路+最短路+打印路径)
Scandinavians often make vacation during the Easter holidays in the largest ski resort Are. Are prov ...
- HDU.1529.Cashier Employment(差分约束 最长路SPFA)
题目链接 \(Description\) 给定一天24h 每小时需要的员工数量Ri,有n个员工,已知每个员工开始工作的时间ti(ti∈[0,23]),每个员工会连续工作8h. 问能否满足一天的需求.若 ...
- 1624 取余最长路(set)
1624 取余最长路 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 佳佳有一个n*m的带权矩阵,她想从(1,1)出发走到(n,m)且只能往右往下移动,她能得到的娱 ...
- 简单Dp----最长公共子序列,DAG最长路,简单区间DP等
/* uva 111 * 题意: * 顺序有变化的最长公共子序列: * 模板: */ #include<iostream> #include<cstdio> #include& ...
- P3119 [USACO15JAN]草鉴定Grass Cownoisseur 分层图或者跑两次最长路
https://www.luogu.org/problemnew/show/P3119 题意 有一个有向图,允许最多走一次逆向的路,问从1再走回1,最多能经过几个点. 思路 (一)首先先缩点.自己在缩 ...
- HDU1529-Casher Emploryment(最最...最经典的差分约束 差分约束-最长路+将环变线)
A supermarket in Tehran is open 24 hours a day every day and needs a number of cashiers to fit its n ...
- 洛谷 P1807 最长路_NOI导刊2010提高(07) 题解
P1807 最长路_NOI导刊2010提高(07) 题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算 ...
- 【春训团队赛第四场】补题 | MST上倍增 | LCA | DAG上最长路 | 思维 | 素数筛 | 找规律 | 计几 | 背包 | 并查集
春训团队赛第四场 ID A B C D E F G H I J K L M AC O O O O O O O O O 补题 ? ? O O 传送门 题目链接(CF Gym102021) 题解链接(pd ...
随机推荐
- Redis主从自动failover
Redis主从架构持久化存在一个问题,即前次测试的结论,持久化需要配置在主实例上才能跨越实例保证数据不丢失,这样以来主实例在持久化数据到硬 盘的过程中,势必会造成磁盘的I/O等待,经过实际测试,这个持 ...
- LoadRunner参数化之数据生成方式
一般需要使用多条数据来完成实际事务的时候,需要参数化.而使用参数化可以方便实现很多实际事务,记得在哪里看到过,参数化是比C函数更高级的函数. 参数化的方法 先来个最常见的LR示例的登录脚本: Acti ...
- 【java 断点续传】
模拟 断点续传 首先,先读取word文件的 一部分 package com.sxd.readLines; import java.io.File; import java.io.FileInputSt ...
- loadrunner以最后出现的字符串为分割符函数实现
void strLastOccr(char inputStr[100], char* outputStr, char *delim){ char value[100],*temp, *t ...
- css3 总结01
前缀 chrome: -webkit- safari: -webkit- firefox: -moz- ie: -ms- opera: -o- 书写的时候应该先用有前缀的样式,再用无前缀的样式 颜色 ...
- struts2总结一:MVC设计模式
设计模式 一.什么是编程里面的设计模式? 1.设计模式是一套被反复使用,多数人知晓的,代码设计经验的总结. 2.模式必须是典型问题(不是个别问题)的解决方案. 二.设计模式的作用 1.解决一类问题的成 ...
- Dependency Injection in ASP.NET Core
Transient – A new instance of the service is created each time it is requested. It can be used for s ...
- EF框架step by step(3)—Code-First
CodeFirst是EF框架的第三种方式,也是最为复杂一种方式,本文将以EF4.1版本为基础,简要讲解一下用法,同时,也介绍DbContext的用法. 本文采用的示例仍然是前两篇采用的博客用户的示例. ...
- WPF中图形表示语法详解(Path之Data属性语法)ZZ
大可山 [MSN:a3news(AT)hotmail.com] http://www.zpxp.com 萝卜鼠在线图形图像处理 ------------------------------------ ...
- HD1847-(博弈论??)
Good Luck in CET-4 Everybody! Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知 ...