https://vjudge.net/contest/66569#problem/B

类试题:noip2013 货物运输

POJ 1797 Heavy Transportation

方法一: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带你飞]专题四 最短路练习的更多相关文章

  1. [kuangbin带你飞]专题四 最短路练习

    对于最短路,我主要使用的就是dijkstra,Floyd,SPFA这三个算法.先来介绍一下这三个算法. 1. dijkstra算法.它适用于边权为正的情况,它是单源最短路,就是从单个源点出发到所有的结 ...

  2. [kuangbin带你飞]专题四 最短路练习 POJ 2253 Frogger

    求第一个点到第二个点的所有通路上最长的边 dijkstra的变形 每次松弛的是每条边通路上的的最长的边 WA了好几次是因为用了%lf 改成%f就过了…… /* ******************** ...

  3. 【算法系列学习】Dijkstra求最短路 [kuangbin带你飞]专题四 最短路练习 D - Silver Cow Party

    https://vjudge.net/contest/66569#problem/D trick:1~N各点到X可以通过转置变为X到1~N各点 #include<iostream> #in ...

  4. 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home

    https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 ...

  5. 【算法系列学习】SPFA邻接表最短路 [kuangbin带你飞]专题四 最短路练习 F - Wormholes

    https://vjudge.net/contest/66569#problem/F 题意:判断图中是否存在负权回路 首先,介绍图的邻接表存储方式 数据结构:图的存储结构之邻接表 邻接表建图,类似于头 ...

  6. [kuangbin带你飞]专题四 最短路练习 POJ 3268 Silver Cow Party

    题意: 在一个有向图中求n头牛从自己的起点走到x再从x走回来的最远距离 思路一开始是暴力跑dij…… 讲道理不太可能…… 然后就百度了一下 才知道把矩阵转置的话就只需要求两次x的单源最短路…… /* ...

  7. [kuangbin带你飞]专题四 最短路练习 POJ 1797 Heavy Transportation

    求每条道路的最大承载量 和上一道题差不多 就是松弛的规则从最大值变成了最小值 /* *********************************************** Author :Su ...

  8. [ An Ac a Day ^_^ ] [kuangbin带你飞]专题四 最短路练习 POJ 2387 Til the Cows Come Home

    求1到N的最短路 注意有重边 跑一遍dijkstra就行 /* *********************************************** Author :Sun Yuefeng ...

  9. [kuangbin带你飞]专题四 最短路练习 G MPI Maelstrom

    #include<iostream> #include<cstring> #include<algorithm> #include<iomanip> # ...

随机推荐

  1. python 接口自动化测试(四)

    说完了SOAP协议的接口自动化 该说下http协议的接口测试了 HttpService.py import requests import sys reload(sys) sys.setdefault ...

  2. 【转】JavaScript 之arguments、caller 和 callee 介绍

    1.前言 arguments, caller ,   callee 是什么? 在JavaScript 中有什么样的作用?本篇会对于此做一些基本介绍. 本文转载自:http://blog.csdn.ne ...

  3. (8)集合之List,ArrayList,LinkedList

    集合的体系结构 Collection 单列集合的接口 |----List 如果实现了List接口的集合类,具备的特点是有序,可重复 |----Set 如果实现了Set接口的集合类,集合特点无序不可重复 ...

  4. iOS 上传文件

    NSString *boundry = @"boundry";//分节符 NSMutableURLRequest *mutableRequest = [NSMutableURLRe ...

  5. deepin系统下如何设置wifi热点(亲测有效)

    deepin系统下如何设置wifi热点(亲测有效) deepin wifi ap linux 热点 首先必须吐槽一下linux下设置wifi太累了....来来回回折腾了我好久的说.心累... 好了废话 ...

  6. js的几种简单排序算法及其效率实测

    function swap(arr,index1,index2){ var t = arr[index1]; arr[index1] = arr[index2]; arr[index2] = t; } ...

  7. XML配置文件的命名空间与Spring配置文件中的头

    一直以来,写Spring配置文件,都是把其他配置文件的头拷贝过来,最多改改版本号,也不清楚哪些是需要的,到底是干嘛的.今天整理一下,拒绝再无脑copy. 一.Spring配置文件常见的配置头 < ...

  8. websocket 项目应用

    序言 很早就想用起来websocket,可惜需要后台服务的支持,技术的翻新总会给我带来巨大的冲击,最近后端人员学习了websocket相关后台技术.于是我们开始动起来了. 学习 这位大兄弟的文章  h ...

  9. Itext中 根据html生成Word文件,包含图片

    package cn.com.wzf; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.Str ...

  10. poptest老李谈分布式与集群

    poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478,咨询电话010-845052 ...