【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 ...
随机推荐
- LR连接oracle时出现:SQLState=28000[Oracle][ODBC][Ora]ORA-01017:invalid username/password;logon denied
出现的现象:
- ubuntu使用笔记
查看自己系统版本: 使用命令:cat /proc/version 查看:proc目录下记录的当前系统运行的各种数据,version记录的版本信息可以直接通过cat查看到,还可以看到我的gcc版本呢. ...
- 利用pushState开发无刷页面切换
转载:http://www.cnblogs.com/flash3d/archive/2013/10/23/3384823.html 实现目标 页面的跳转(前进后退,点击等)不重新请求页面 页面URL与 ...
- asp中 grideview 更新 无法获取值 解决办法
string str1 = ((TextBox)(GridView1.Rows[e.RowIndex].Cells[7].Controls[0])).Text.ToString().Trim(); 来 ...
- 前端学PHP之文件操作(认真读读)
前面的话 在程序运行时,程序本身和数据一般都存在内存中,当程序运行结束后,存放在内存中的数据被释放.如果需要长期保存程序运行所需的原始数据,或程序运行产生的结果,就需要把数据存储在文件或数据库.一般地 ...
- iOS实现简书的账号识别方式(正则表达式)
通过简书iOS客户端登录,我们会看到请输入手机号或者邮箱登录,但是我们随机输入1234567的时候,便会弹出手机格式不正确,同样也会识别我们的邮箱格式,那么我们在项目中怎么实现这种判断呢? 0E471 ...
- .net平台下C#socket通信(中)
上篇.net平台下C#socket通信(上)介绍了socket通信的基本原理及最基本的通信方式.本文在此基础上就socket通信时经常遇到的问题做一个简单总结,都是项目中的一些小问题,拿来此处便于下次 ...
- SQLite错误码
在SQLite中,执行SQL语句的sqlite3_exec()和sqlite3_prepare()两个核心方法的返回值都是一个整型数据,因此,当程序执行出现错误时,我们可以根据执行返回的整型数据来判断 ...
- 完数[HDU1406]
完数 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- 【POJ2096】Collecting Bugs 期望
[POJ2096]Collecting Bugs Description Ivan is fond of collecting. Unlike other people who collect pos ...