【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 ...
随机推荐
- Activity之间传递数据的方式及常见问题总结
Activity之间传递数据一般通过以下几种方式实现: 1. 通过intent传递数据 2. 通过Application 3. 使用单例 4. 静态成员变量.(可以考虑 WeakReferences) ...
- ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步
一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...
- JavaScript 入门 (1)
一. javascript的调用 JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到<head>中: <html> <hea ...
- SPOJ DISUBSTR 后缀数组
题目链接:http://www.spoj.com/problems/DISUBSTR/en/ 题意:给定一个字符串,求不相同的子串个数. 思路:直接根据09年oi论文<<后缀数组——出来字 ...
- idea 使用
1.idea对maven的兼容性优于eclipse,idea对于程序内部管理是模块,个人感觉也是优于eclipse. 2.idea默认设置编辑器字体是比较差的. 可以参考文章 http://www.3 ...
- css -- 导航条
1.垂直导航条 HTML: <ul class="nav"> <li><a href="">Home</a>&l ...
- git merge 与 rebase 的区别
http://gitbook.liuhui998.com/4_2.html merge rebase
- 解决Ue4C++使用UMG之类的模块时出现的拼写错误
在cs文件中加入UMG模块后,在项目文件上右键生成项目文件即可解决
- js事件绑定细节说明
javascript绑定事件: 经常用jQuery去写,时间长了对原生态的js事件绑定的知识会慢慢淡化或者遗忘了,必须翻出来再次总结,今天再次把js原生态事件的处理做个总结. 从最初开始,谁刚接触ja ...
- 11039 - Building designing
Building designing An architect wants to design a very high building. The building will consist o ...