题目传送门

  

题目描述

每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快。还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法永远是'S'……还有不能忘了,胖子的歌声永远是让我们惊叫的!!

今天是野猫的生日,所以想到这些也正常,只是因为是上学日,没法一起去玩了。但回忆一下那时的甜蜜总是一种幸福嘛。。。

但是每次集合的时候都会出现问题!野猫是公认的“路盲”,野猫自己心里也很清楚,每次都提前出门,但还是经常迟到,这点让大家很是无奈。后来,野猫在每次出门前,都会向花儿咨询一下路径,根据已知的路径中,总算能按时到了。

现在提出这样的一个问题:给出n个点的坐标,其中第一个为野猫的出发位置,最后一个为大家的集合位置,并给出哪些位置点是相连的。野猫从出发点到达集合点,总会挑一条最近的路走,如果野猫没找到最近的路,他就会走第二近的路。请帮野猫求一下这条第二最短路径长度。

输入输出格式

输入格式:

第一行是两个整数n(1<=n<=200)和m,表示一共有n个点和m条路,以下n行每行两个数xi,yi,(-500<=xi,yi<=500),代表第i个点的坐标,再往下的m行每行两个整数pj,qj,(1<=pj,qj<=n),表示两个点相通。

输出格式:

只有一行包含一个数,为第二最短路线的距离(保留两位小数),如果存在多条第一短路径,则答案就是第一最短路径的长度;如果不存在第二最短路径,输出-1。

输入输出样例

输入样例#1: 复制

3 3
0 0
1 1
0 2
1 2
1 3
2 3
输出样例#1: 复制

2.83

说明

各个测试点1s


  分析:开始在网上看到了一个Dijkstra算法一次性求最短路和次短路,然后决定来拿这题练手,结果...感人肺腑的卡了两个小时,死活有两个点会wa掉。最后没办法就索性打了个暴力spfa+删边。。。然后之前那个还没调对。。。两份代码都放一下吧。

  Code:

(Dijkstra)

#include<bits/stdc++.h>
using namespace std;
const int N=;
#define INF 1e9+7
typedef pair<double,int>P;
int n,m;
double di[N][N],dis[N],dist[N];
struct pos{int x,y;}a[N];
struct node{
int to;double val;
node(int x=,double y=):
to(x),val(y){}};
vector<node>g[N];
void dijkstra()
{
priority_queue<P, vector<P>, greater<P> >team;
fill(dis,dis+n+,INF);
fill(dist,dist+n+,INF);
dis[]=;
team.push(P(,));
while(!team.empty()){
P p=team.top();team.pop();
int x=p.second;
double d=p.first;
if(dist[x]<d)continue;
for(int i=;i<g[x].size();i++){
node e=g[x][i];
double dt=d+e.val;
if(dis[e.to]>dt){
swap(dis[e.to],dt);
team.push(P(dis[e.to],e.to));
}
if(dist[e.to]>dt&&dis[e.to]<dt){
dist[e.to]=dt;
team.push(P(dist[e.to],e.to));
}
}
}
if(dist[n]<dist[])
printf("%.2lf",dist[n]);
else
printf("-1");
}
double get(int A,int B)
{
double x1=a[A].x*1.0,y1=a[A].y*1.0;
double x2=a[B].x*1.0,y2=a[B].y*1.0;
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
scanf("%d%d",&n,&m);
int x,y;
for(int i=;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
for(int i=;i<n;i++)
for(int j=i+;j<=n;j++)
di[i][j]=di[j][i]=get(i,j);
for(int i=;i<=m;i++){
scanf("%d%d",&x,&y);
g[x].push_back(node{y,di[x][y]});
g[y].push_back(node{x,di[y][x]});}
dijkstra();
return ;
}

(SPFA+删边)

#include<bits/stdc++.h>
#define Fi(a,b,c) for(int a=b;a<=c;a++)
#define Fx(a,b,c) for(int a=b;a>=c;a--)
using namespace std;
const int N=;
int n,m,head[N],size,pre[N];
double d[N][N],dis[N],ans;
bool vis[N];
struct Poi{int x,y;}a[N];
struct Node{
int to,next;double val;
}edge[N<<];
inline int read()
{
char ch=getchar();int num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
return flag?-num:num;
}
inline void add(int x,int y,double z)
{
edge[++size].to=y;
edge[size].val=z;
edge[size].next=head[x];
head[x]=size;
}
inline double get(int x,int y)
{
double x1=a[x].x*1.0,y1=a[x].y*1.0;
double x2=a[y].x*1.0,y2=a[y].y*1.0;
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void spfa()
{
memset(vis,false,sizeof(vis));
Fi(i,,n)dis[i]=0x3f3f3f3f;
queue<int>team;team.push();
dis[]=;vis[]=true;
while(!team.empty()){
int x=team.front();team.pop();vis[x]=false;
for(int i=head[x];i!=-;i=edge[i].next){
int y=edge[i].to;
if(dis[y]>dis[x]+edge[i].val){
dis[y]=dis[x]+edge[i].val;pre[y]=x;
if(!vis[y]){team.push(y);vis[y]=true;}}}}
}
inline double SPFA(int u,int v)
{
memset(vis,false,sizeof(vis));
Fi(i,,n)dis[i]=0x3f3f3f3f;
queue<int>team;team.push();
dis[]=;vis[]=true;
while(!team.empty()){
int x=team.front();team.pop();vis[x]=false;
for(int i=head[x];i!=-;i=edge[i].next){
int y=edge[i].to;if((x==u&&y==v)||(x==v&&y==u))continue;
if(dis[y]>dis[x]+edge[i].val){
dis[y]=dis[x]+edge[i].val;
if(!vis[y]){team.push(y);vis[y]=true;}}}}
return dis[n];
}
int main()
{
n=read();m=read();
memset(head,-,sizeof(head));
Fi(i,,n)a[i].x=read(),a[i].y=read();
Fi(i,,n-) Fi(j,i+,n)
d[i][j]=d[j][i]=get(i,j);
Fi(i,,m){int x=read();int y=read();
add(x,y,d[x][y]);add(y,x,d[y][x]);}
spfa();ans=0x3f3f3f3f;int f=n;
while(){
double ka=SPFA(pre[f],f);
if(ans>ka)ans=ka;f=pre[f];
if(f==)break;}
if(ans>)printf("-1");
else printf("%.2lf",ans);
return ;
}

洛谷P1491 集合位置 [最短路,SPFA]的更多相关文章

  1. 洛谷 P1491 集合位置

    P1491 集合位置 题目描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的 ...

  2. 洛谷P1491集合位置

    传送门啦 这个题说白了就是求一个次短路. 方法是我们先跑一遍最短路,记录下最短路上每一个点的前驱.然后我们将最短路上每一条边都标记一次,分别跑一边最短路,求出最短路径即可. 在这我们不用特殊判断是否是 ...

  3. P1491 集合位置 次短路

    这个题是一个次短路的裸题,就是把最短路路径求出来之后依次删边,然后跑最短路,在这些情况里取最小值就行了. 题干: 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家 ...

  4. AC日记——集合位置 洛谷 P1491

    集合位置 思路: 次短路: 先走一遍最短路: 记录最短路径,然后依次删边走最短路: 最短的长度就是次短路: 来,上代码: #include <queue> #include <cma ...

  5. NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序

    原文链接https://www.cnblogs.com/zhouzhendong/p/9258043.html 题目传送门 - 洛谷P3953 题目传送门 - Vijos P2030 题意 给定一个有 ...

  6. P1491 集合位置

    题目描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法 ...

  7. vijos:P1155集合位置(次短路)

    描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法永远 ...

  8. 【题解】洛谷P2296 [NOIP2014TG] 寻找道路(SPFA+DFS)

    题目来源:洛谷P2296 思路 一开始看还以为是一道水题 虽然本来就挺水的 本道题的难点在于如何判断是否路径上的点都会直接或者间接连着终点 我们需要在一开始多建一个反向图 然后从终点DFS回去 把路径 ...

  9. 洛谷 P1466 集合 Subset Sums Label:DP

    题目描述 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的.举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,每个子 ...

随机推荐

  1. Nginx简介及使用Nginx实现负载均衡的原理【通俗易懂,言简意赅】【转】

    Nginx 这个轻量级.高性能的 web server 主要可以干两件事情: 直接作为http server(代替apache,对PHP需要FastCGI处理器支持): 另外一个功能就是作为反向代理服 ...

  2. 在linux下创建软链接(即目录映射)

    在linux中创建软链接,使用命令:ln -s. 语法:ln -s 源文件 目标文件.

  3. MySQL和Postgresql的区别

    一.PostgreSQL相对于MySQL的优势 1.在SQL的标准实现上要比MySQL完善,而且功能实现比较严谨:2.存储过程的功能支持要比MySQL好,具备本地缓存执行计划的能力:3.对表连接支持较 ...

  4. 模板复习【updating】

    马上就要noi了……可能滚粗已经稳了……但是还是要复习模板啊 LCT: bzoj2049 1A 7min # include <stdio.h> # include <string. ...

  5. 【BZOJ】1486 [HNOI2009]最小圈

    [算法]二分+spfa [题解]据说这个叫分数规划? 0-1分数规划 二分答案a,则对于任意的环有w/k≤a即w-ak≤0,若满足条件则a变小,否则a变大. 因为w=w1+w2+...+wk,所以变形 ...

  6. UITableView---iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址  //转载请注明出处--本文永久链接:http://www.cnblogs.com/C ...

  7. 使用ubuntun16.04代码笔记

    (1)cd  /代表到根目录下面:ls表示将盘中内容列出:cd  /home表是打开根目录下的home文件夹:(注意:凡是根目录下的文件夹前面都要加 /) (2)快捷键方式:可以用tab自动补全 (1 ...

  8. 【Eclipse】Eclipse中修改项目的映射名称与端口

    1.正常部署(映射的名字为项目名字,端口为8080)

  9. github新建托管项目及上传项目

    一.新建托管项目 1.注册: 2.点击new repositories新建一个新项目: 3.输入项目名称及项目描述,Create repository: 4.点击右边栏的剪切板图标,记录下你的项目地址 ...

  10. ARM linux的启动部分源代码简略分析【转】

    转自:http://www.cnblogs.com/armlinux/archive/2011/11/07/2396784.html ARM linux的启动部分源代码简略分析 以友善之臂的mini2 ...