【算法系列学习】Dijkstra算法变形 [kuangbin带你飞]专题四 最短路练习
https://vjudge.net/contest/66569#problem/B
类试题:noip2013 货物运输
方法一:Dijkstra变形
http://blog.csdn.net/u013446688/article/details/42777173
关键在于对松弛的变形,这里不是求源点到每个点的所有路径中的路径长度最小值,而是求源点到每个点的所有路径中Frog distance(路径中的最大距离)的最小值
所以dis[k]=min(dis[k],dis[v]+map[v][k])变成了dis[k]=min(dis[k],max(dis[v],map[v][k]))
这里的dis[k]不再是源点到结点k所有路径中路径长度的最小值,而是源点到结点k所有路径中Frog distance(路径中的最大距离)的最小值。
为了理解dis[k]=min(dis[k],max(dis[v],map[v][k])),我们可以做这样的假设:源点到v的路径有三条,这三条路径的frog distance分别是3,4,5;那么dis[v]就是3。
现在分两种情况分别进行讨论:
1.map[v][k]>dis[v],由于源点经过v到达k的路径也有三条,这三条的frog distance就分别变成了map[v][k],max(4,map[v][k]),max(5,map[v][k]);那么dis[k]就一定是最小值map[v][k].
2.map[v][k]<=dis[v],则这三条路径的frog distance 还是3,4,5.dis[k]就等于dis[v]
下面是AC的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
const double inf=0x3f3f3f3f;
using namespace std;
int n;
struct node
{
int x,y;
}nd[];
double map[][];
double dist(node a,node b)
{
return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y));
}
double dis[];
void Dijkstra()
{
bool vis[];
memset(vis,,sizeof(vis));
dis[]=0.0;
for(int i=;i<=n;i++)
{
dis[i]=inf;
}
int v;
for(int i=;i<=n;i++)
{
int m=inf;
for(int k=;k<=n;k++)
{
if(!vis[k]&&dis[k]<m)
{
m=dis[k];
v=k;
}
}
vis[v]=;
//对以v为顶点的边进行松弛
for(int k=;k<=n;k++)
{
if(!vis[k])
{
dis[k]=min(dis[k],max(dis[v],map[v][k]));
}
}
}
}
int main()
{
int kas=;
while(scanf("%d",&n)&&n)
{
for(int i=;i<=n;i++)
{
scanf("%d%d",&nd[i].x,&nd[i].y);
for(int k=;k<i;k++)
{
map[i][k]=map[k][i]=dist(nd[i],nd[k]);
}
}
Dijkstra();
if(kas!=)
{
printf("\n");
}
printf("Scenario #%d\n",kas++);
printf("Frog Distance = %.3f\n",dis[]);
}
return ;
}
Dijkstra
要注意四点:
1.sqrt()要强制转化为double
2.double不能用memset(dis,inf,sizeof(dis))
3.
for(int k=1;k<=n;k++)
{
if(!vis[k])
{
dis[k]=min(dis[k],max(dis[v],map[v][k]));
}
}
不写vis[k]也对,但是增加时间复杂度
4.注意输入输出,最后一个样例之后是没有空行的
方法二:二分+并查集
http://xwk.iteye.com/blog/2129453
二分出一个mid值表示最大边的长度,然后遍历所有边,只要当前边的长度不超过mid,就合并当前边所连接的两个点。最后判断1和2在不在同一个连通分量上,如果是则说明当前mid已经足够,为了找到mid的最小值,R=mid.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath> using namespace std;
const int maxn=2e2+;
const double eps=1e-;
int n;
struct node
{
int x,y;
}nd[maxn];
double map[maxn][maxn];
double dist(const node& a,const node& b)
{
return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y));
}
int fa[maxn];
int find(int i)
{
if(fa[i]==-)
{
return i;
}
return fa[i]=find(fa[i]);
}
bool bind(int i,int k)
{
i=find(i);
k=find(k);
if(i!=k)
{
fa[i]=k;
}
return true;
}
bool ok(double mid)
{
memset(fa,-,sizeof(fa));
//加进去的边的最大值为mid
for(int i=;i<=n;i++)
{
for(int k=i+;k<=n;k++)
{
if(map[i][k]<mid)
{
bind(i,k);
}
}
}
return find()==find();
} int main()
{
int kas=;
while(scanf("%d",&n)&&n)
{
for(int i=;i<=n;i++)
{
scanf("%d%d",&nd[i].x,&nd[i].y);
for(int k=;k<i;k++)
{
map[i][k]=map[k][i]=dist(nd[i],nd[k]);
}
}
double l=0.0;
double r=map[][];
while(r-l>eps)
{
double mid=(l+r)/;
if(ok(mid))
{
r=mid;
}
else
{
l=mid;
}
}
if(kas!=)
{
printf("\n");
}
printf("Scenario #%d\n",kas++);
printf("Frog Distance = %.3f\n",r);
}
return ;
}
二分+并查集
注意在ok函数里,每次都要初始化memset(fa,-1,sizeof(fa));
方法三:最小生成树
http://blog.csdn.net/shouwang_tomorrow/article/details/47616983
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath> using namespace std;
int n;
int cnt;
const int maxn=2e4+; struct edge
{
int x,y;
double w;
}e[maxn];
struct node
{
int x;
int y;
}nd[];
double dist(const node& a,const node& b)
{
return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y));
}
bool cmp(const edge& a,const edge& b)
{
return a.w<b.w;
}
int fa[maxn];
int find(int i)
{
if(fa[i]==-)
{
return i;
}
return fa[i]=find(fa[i]);
}
bool bind(int i,int k)
{
i=find(i);
k=find(k);
if(i!=k)
{
fa[i]=k;
return true;
}
return false;
}
double Kruskal()
{
for(int i=;i<cnt;i++)
{
if(bind(e[i].x,e[i].y))
{
if(find()==find())
{
return e[i].w;
}
}
}
}
int main()
{
int kas=;
while(scanf("%d",&n)&&n)
{
cnt=;
for(int i=;i<=n;i++)
{
scanf("%d%d",&nd[i].x,&nd[i].y);
for(int k=;k<i;k++)
{
e[cnt].x=i;
e[cnt].y=k;
e[cnt++].w=dist(nd[i],nd[k]);
}
}
sort(e,e+cnt,cmp);
memset(fa,-,sizeof(fa));
double ans=Kruskal();
if(kas!=)
{
printf("\n");
}
printf("Scenario #%d\nFrog Distance = %.3f\n",kas++,ans);
}
return ;
}
Kruskal
【算法系列学习】Dijkstra算法变形 [kuangbin带你飞]专题四 最短路练习的更多相关文章
- [kuangbin带你飞]专题四 最短路练习
对于最短路,我主要使用的就是dijkstra,Floyd,SPFA这三个算法.先来介绍一下这三个算法. 1. dijkstra算法.它适用于边权为正的情况,它是单源最短路,就是从单个源点出发到所有的结 ...
- [kuangbin带你飞]专题四 最短路练习 POJ 2253 Frogger
求第一个点到第二个点的所有通路上最长的边 dijkstra的变形 每次松弛的是每条边通路上的的最长的边 WA了好几次是因为用了%lf 改成%f就过了…… /* ******************** ...
- 【算法系列学习】Dijkstra求最短路 [kuangbin带你飞]专题四 最短路练习 D - Silver Cow Party
https://vjudge.net/contest/66569#problem/D trick:1~N各点到X可以通过转置变为X到1~N各点 #include<iostream> #in ...
- 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home
https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 ...
- 【算法系列学习】SPFA邻接表最短路 [kuangbin带你飞]专题四 最短路练习 F - Wormholes
https://vjudge.net/contest/66569#problem/F 题意:判断图中是否存在负权回路 首先,介绍图的邻接表存储方式 数据结构:图的存储结构之邻接表 邻接表建图,类似于头 ...
- [kuangbin带你飞]专题四 最短路练习 POJ 3268 Silver Cow Party
题意: 在一个有向图中求n头牛从自己的起点走到x再从x走回来的最远距离 思路一开始是暴力跑dij…… 讲道理不太可能…… 然后就百度了一下 才知道把矩阵转置的话就只需要求两次x的单源最短路…… /* ...
- [kuangbin带你飞]专题四 最短路练习 POJ 1797 Heavy Transportation
求每条道路的最大承载量 和上一道题差不多 就是松弛的规则从最大值变成了最小值 /* *********************************************** Author :Su ...
- [ An Ac a Day ^_^ ] [kuangbin带你飞]专题四 最短路练习 POJ 2387 Til the Cows Come Home
求1到N的最短路 注意有重边 跑一遍dijkstra就行 /* *********************************************** Author :Sun Yuefeng ...
- [kuangbin带你飞]专题四 最短路练习 G MPI Maelstrom
#include<iostream> #include<cstring> #include<algorithm> #include<iomanip> # ...
随机推荐
- 队列工厂之RedisMQ
本次和大家分享的是RedisMQ队列的用法,前两篇文章队列工厂之(MSMQ)和队列工厂之RabbitMQ分别简单介绍对应队列环境的搭建和常用方法的使用,加上本篇分享的RedisMQ那么就完成了咋们队列 ...
- curl javaSSm框架中传入json数组的格式方法
curl与java结合传入get.post,head请求, 比如: curl的地址: curl -l 127.0.0.1:8080/spacobj/core/do?acid=100 -H " ...
- fastjson将json格式null转化空串
生成JSON代码片段 Map < String , Object > jsonMap = new HashMap< String , Object>(); jsonMap.pu ...
- 标准之路网站上一篇文章《十天学会web标准(div+css)》的营养精华
以下精华出自如下链接,“http://www.aa25.cn/special/10day/index.shtml”,<十天学会web标准(DIV+CSS)>. 这个内容不要删掉:“< ...
- Cesium原理篇:3D Tiles(3)个人总结
个人结论:目前,在演示层面,3D Tiles问题不大,但项目应用上就不够成熟了,所以问问自己,你是想吃瓜呢还是想吃螃蟹? 好的方面 数据规范 我非常喜欢glTF的整体设计,概括有四点:第一,数据块(B ...
- 机器学习 - pycharm, pyspark, spark集成篇
AS WE ALL KNOW,学机器学习的一般都是从python+sklearn开始学,适用于数据量不大的场景(这里就别计较“不大”具体指标是啥了,哈哈) 数据量大了,就需要用到其他技术了,如:spa ...
- react+webpack开发环境配置
react是目前非常热门的前端框架,提倡组件化开发.所谓的组件,简单理解,就是一个独立的页面部件(包括页面模版,样式,逻辑等),它是一个独立的整体. webpack,是一个模块打包工具,其主要功能,就 ...
- JSTL 核心标签库 使用(转)
在JSP的开发中,迭代是经常要使用到的操作.例如,逐行的显示查询的结果等.在早期的JSP中,通常使用Scriptlets来实现Iterator或者Enumeration对象的迭代输出.现在,通过JST ...
- 老李推荐:第1章2节《MonkeyRunner源码剖析》概述:边界
老李推荐:第1章2节<MonkeyRunner源码剖析>概述:边界 边界 怎么样才算分析清楚一个事物的原理是什么呢?就以前面提到的<LINUX内核源代码情景分析>为例子,分 ...
- Framework7首页隐藏navbar其他页面显示navbar
Framework7首页隐藏navbar其他页面显示navbar 帮别人解决问题,自己也记录一下, 首页.navbar加.navbar-hidden, 首页.page加.no-navbar, 如果首页 ...