题目描述

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


大概就是求次短路
好像可以用A*来求k短路,不过我不会。。。
那就换一种思路
既然不是最短路,那么它的路径就一定不能和最短路完全重合
也就是说,至少会有一条边与最短路不同
但是我们不知道哪条/哪些边会与最短路不同
那么我们在第一次spfa时记录下来路径(前驱结点)
然后我们就枚举边,将最短路里的每条边都删去一次之后再跑一边spfa求最短路
这个题显然两个点之间只会有一条边相连,所以这个题中枚举边等价于枚举最短路上的相邻两点
这样求出次短路
而且最多也就只有200个点,所以这种方法是行得通的!
代码(跑的比较慢,空间占的也比较多,有空可能会优化一下。。。):

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#define For(i,l,r) for(int i=l;i<=r;++i)
using namespace std;
int read()
{char c;bool t=0;int a=0;while((c=getchar())==' '||c=='\n'||c=='\r');if(c=='-'){t=1;c=getchar();}while(isdigit(c)){a*=10;a+=(c-'0');c=getchar();}return a*(t?-1:1);
}
struct line{int to,next;double v;
}edge[80010];
struct poi{int x,y;
}node[201];
int last[201],pre[201],n,m;
double dis[201];
bool vis[201];
double dist(int x,int y)
{return sqrt((node[x].x-node[y].x)*(node[x].x-node[y].x)+(node[x].y-node[y].y)*(node[x].y-node[y].y));
}
void add(int from,int to,int i)
{edge[i].next=last[from];last[from]=i;edge[i].to=to;edge[i].v=dist(from,to);
}
void spfa()
{int tx;memset(dis,127,sizeof dis);queue<int> q;q.push(1);dis[1]=0;vis[1]=1;while(!q.empty()){tx=last[q.front()];while(tx){if(dis[q.front()]+edge[tx].v<dis[edge[tx].to]){dis[edge[tx].to]=dis[q.front()]+edge[tx].v;pre[edge[tx].to]=q.front();if(!vis[edge[tx].to]){q.push(edge[tx].to);vis[edge[tx].to]=1;}}tx=edge[tx].next;}vis[q.front()]=0;q.pop();}return;
}
void spfa2(int x,int y)
{int tx;memset(dis,127,sizeof dis);queue<int> q;q.push(1);dis[1]=0;vis[1]=1;while(!q.empty()){tx=last[q.front()];while(tx){if((q.front()==x&&edge[tx].to==y)||(q.front()==y&&edge[tx].to==x)){tx=edge[tx].next;continue;}if(dis[q.front()]+edge[tx].v<dis[edge[tx].to]){dis[edge[tx].to]=dis[q.front()]+edge[tx].v;if(!vis[edge[tx].to]){q.push(edge[tx].to);vis[edge[tx].to]=1;}}tx=edge[tx].next;}vis[q.front()]=0;q.pop();}return;
}
int main()
{int tx,ty,now;double ans=0,tmp;n=read();m=read();now=n;m+=m;For(i,1,n){node[i].x=read();node[i].y=read();}For(i,1,m){tx=read();ty=read();add(tx,ty,i++);add(ty,tx,i);}spfa();while(now!=1){spfa2(now,pre[now]);if(dis[n]<ans||!ans)ans=dis[n];now=pre[now];}printf("%.2f",ans);return 0;
}

Luogu P1491 集合位置 (spfa--次短路)相关推荐

  1. 洛谷 P1491 集合位置

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

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

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

  3. 集合位置(洛谷 P1491)

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

  4. TYVJ P2032 「Poetize9」升降梯上 spfa最短路

    %%%暴搜出奇迹%%%@SiriusRen 其实我刚开始题读错了,才导致我写图论... spfa跑最短路,开一个node记录状态(pair当然滋磁):所在楼层和槽的位置 以层数为1,槽在0的位置 为初 ...

  5. [APIO2013]机器人(DP+SPFA最短路)

    [APIO2013]机器人 description solution dpl,r,i,j:dp_{l,r,i,j}:dpl,r,i,j​: 在(i,j)(i,j)(i,j)位置合并编号为[l,r][l ...

  6. 算法提高课-图论-单源最短路的建图方式-AcWing 1127. 香甜的黄油:spfa最短路

    题目分析 来源:acwing 分析: 多源汇最短路.所以我们首先想到的是floyd算法, 可是它的复杂度是O(n3)O(n^3)O(n3),会超时.所以我们需要另外考虑. 任意一个点作为起点求出到所有 ...

  7. [ICPC Asia Nanjing 2019] Holy Grail (spfa最短路)

    题意:给出一个n个点,m条边的有向图,再给6组询问,在u,v间建一条权值最小的边,使图中没有负环.保证有解. 做法:u,v加边,如果有负环必定过u,v.以v为起点,到u的最短路和u->v组成的环 ...

  8. 洛谷 P1606 [USACO07FEB]荷叶塘Lilypad Pond(spfa+最短路计数) 题解

    题目来源: https://www.luogu.org/problemnew/show/P1606 题目描述: 题目描述 FJ has installed a beautiful pond for h ...

  9. P1462 通往奥格瑞玛的道路(二分 迪杰斯特拉 最短路 + spfa最短路算法)

    题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...

最新文章

  1. hadoop的两大核心之一:HDFS总结
  2. 如何用C代码生成二维码
  3. VMM2012应用指南之3-安装VMM2012
  4. Fedora 18 下安装 mplayer
  5. 共享会话怎么设置没访问自动断开_谁总结的JavaWeb会话技术了?太全面了...
  6. [NOI2015Day1]解题报告
  7. Java架构师 JD汇总
  8. @Qualifier注解 的理解和使用
  9. Kaggle案例泰坦尼克号问题
  10. 原生js的e.target.closest()方法
  11. Android Fragment 从源码的角度去解析(上)
  12. [转载]livid 写给他自己的
  13. 这个小程序厉害了!一键生成花式昵称,让你的微信从此与众不同!
  14. 《青春舞曲》教学设计
  15. gitee如何解决GitHub下载速度慢的问题
  16. Blazor University (47)依赖注入 —— Singleton 依赖
  17. Windows与Linux系统信号与thread
  18. 做IT的考什么证书含金量高?对带项目和招标有作用的?
  19. pyqt5 同时显示多个画面_体育赛事直播应用NHL.TV可让屏幕同时显示6个画面,全景观看比赛...
  20. 一建今年大放水,23年会不会难度剧增?

热门文章

  1. pmsm什么意思_PMSM是什么意思
  2. 同创伟业王维:行业泡沫期易诞生伟大公司
  3. 【Python 实战基础】什么是PyQt6? 简单介绍一下PyQt6
  4. win7系统没有诊断策略服务器,Win7提示诊断策略服务未运行无法诊断检查网络解决方法...
  5. App 用户新体验——Agora Native SDK 3.4.0
  6. 中国智能控制器行业“十四五”投资规划及前景趋势报告2022~2028年
  7. Weird Rounding
  8. 新建gitlab分支
  9. Apache DolphinScheduler 在叽里呱啦的实战经验
  10. 海子-JVM的内存区域划分