【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 ...
随机推荐
- 用ajax和js怎么做出滚动条滚到最下面分页
获取滚动条位置(scrollTop) 获取可视窗口高度(viewportHeight) 获取整个页面可滚动高度(scrollHeight) 当scrollTop+viewportHeight==scr ...
- jvm运行机制与内存管理
http://blog.csdn.net/lengyuhong/article/details/5953544 http://www.cnblogs.com/nexiyi/p/java_memory_ ...
- Color the ball(线段树)
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- 微软开放WP开发者回复用户应用评论功能
1 4月18日,据The NextWeb网站报道,微软今天公布了一项新的开发者试点项目:回复Windows Phone应用评论.该公司表示,它们将在本周推出这项功能,不过目前仅对部分开发者开放. ...
- Hadoop 分布式环境搭建
一.前期环境 安装概览 IP Host Name Software Node 192.168.23.128 ae01 JDK 1.7 NameNode, SecondaryNameNode, Data ...
- Ext中Grid重新load设置URL
一.前言 Extjs中grid网格有时候需要重新加载,加载的时候对应不同的URL,什么情况出现:有需要我们在添加附件的时候,添加完成了附件,需要把另一个show添加的数据重新加载到grid中,而 ...
- BZOJ1012[JSOI2008]最大数maxnumber 题解
题目大意: 维护一个数列,有两种操作:1. 查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2.插入操作:将n加上t,其中t是最近一次查询操作的答案(如果还未执行 ...
- Codeforces Round #253 (Div. 2) D. Andrey and Problem
关于证明可以参考题解http://codeforces.com/blog/entry/12739 就是将概率从大到小排序然后,然后从大到小计算概率 #include <iostream> ...
- BZOJ 1083 题解
1083: [SCOI2005]繁忙的都市 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2431 Solved: 1596[Submit][Sta ...
- [BZOJ2791][Poi2012]Rendezvous
2791: [Poi2012]Rendezvous Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 95 Solved: 71[Submit][Sta ...