P1491 集合位置 次短路
这个题是一个次短路的裸题,就是把最短路路径求出来之后依次删边,然后跑最短路,在这些情况里取最小值就行了。
题干:
每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快。还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法永远是'S'……还有不能忘了,胖子的歌声永远是让我们惊叫的!! 今天是野猫的生日,所以想到这些也正常,只是因为是上学日,没法一起去玩了。但回忆一下那时的甜蜜总是一种幸福嘛。。。 但是每次集合的时候都会出现问题!野猫是公认的“路盲”,野猫自己心里也很清楚,每次都提前出门,但还是经常迟到,这点让大家很是无奈。后来,野猫在每次出门前,都会向花儿咨询一下路径,根据已知的路径中,总算能按时到了。 现在提出这样的一个问题:给出n个点的坐标,其中第一个为野猫的出发位置,最后一个为大家的集合位置,并给出哪些位置点是相连的。野猫从出发点到达集合点,总会挑一条最近的路走,如果野猫没找到最近的路,他就会走第二近的路。请帮野猫求一下这条第二最短路径长度。
输入输出格式
输入格式: 第一行是两个整数n(<=n<=)和m,表示一共有n个点和m条路,以下n行每行两个数xi,yi,(-<=xi,yi<=),代表第i个点的坐标,再往下的m行每行两个整数pj,qj,(<=pj,qj<=n),表示两个点相通。 输出格式: 只有一行包含一个数,为第二最短路线的距离(保留两位小数),如果存在多条第一短路径,则答案就是第一最短路径的长度;如果不存在第二最短路径,输出-。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
#define mp make_pair
#define pr pair<db,int>
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = 1e5 + ;
struct node
{
int l,r,nxt;
db w;
}a[ * N];
int lst[N],len = ;
int n,m,px[N],py[N];
db dis[N];
int vis[N],pre[N];
void add(int x,int y,db w)
{
a[++len].l = x;
a[len].r = y;
a[len].w = w;
a[len].nxt = lst[x];
lst[x] = len;
}
db dist(int x,int y)
{
return sqrt((db)(px[x] - px[y]) * (px[x] - px[y]) + (db)(py[x] - py[y]) * (py[x] - py[y]));
}
priority_queue <pr,vector<pr>,greater<pr> > qu;
void dij()
{
clean(vis);
duke(i,,n)
{
dis[i] = ;
}
dis[] = ;
qu.push(mp(dis[],));
while(!qu.empty())
{
pr u = qu.top();
qu.pop();
int x = u.second;
if(vis[x])
continue;
vis[x] = ;
// cout<<x<<endl;
for(int k = lst[x];k;k = a[k].nxt)
{
int y = a[k].r;
// cout<<x<<" "<<y<<" "<<dis[y]<<" "<<dis[x]<<" "<<a[k].w<<endl;
if(dis[y] > dis[x] + a[k].w)
{
dis[y] = dis[x] + a[k].w;
pre[y] = x;
qu.push(mp(dis[y],y));
}
}
}
// cout<<dis[n]<<endl;
}
db DIJ(int l,int r)
{
clean(vis);
duke(i,,n)
{
dis[i] = ;
}
dis[] = ;
qu.push(mp(dis[],));
while(!qu.empty())
{
pr u = qu.top();
qu.pop();
int x = u.second;
if(vis[x])
continue;
vis[x] = ;
for(int k = lst[x];k;k = a[k].nxt)
{
int y = a[k].r;
if((x == l && y == r) || (y == l && x == r))
{
// cout<<"ok"<<endl;
continue;
}
if(dis[y] > dis[x] + a[k].w)
{
dis[y] = dis[x] + a[k].w;
pre[y] = x;
qu.push(mp(dis[y],y));
}
}
}
return dis[n];
}
int main()
{
read(n);read(m);
duke(i,,n)
read(px[i]),read(py[i]);
duke(i,,m)
{
int x,y;
read(x);read(y);
// cout<<dist(x,y)<<" "<<px[x]<<" "<<py[x]<<" "<<px[y]<<" "<<py[y]<<endl;
add(x,y,dist(x,y));
add(y,x,dist(x,y));
}
dij();
db minn = ;
int l,r = n;
while(r != )
{
l = r;
r = pre[l];
// cout<<l<<" "<<r<<endl;
minn = min(DIJ(l,r),minn);
}
if(minn == )
printf("-1\n");
else
printf("%.2lf\n",minn);
return ;
}
P1491 集合位置 次短路的更多相关文章
- 洛谷P1491 集合位置 [最短路,SPFA]
题目传送门 题目描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记 ...
- 洛谷 P1491 集合位置
P1491 集合位置 题目描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的 ...
- P1491 集合位置
题目描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法 ...
- vijos:P1155集合位置(次短路)
描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法永远 ...
- 洛谷P1491集合位置
传送门啦 这个题说白了就是求一个次短路. 方法是我们先跑一遍最短路,记录下最短路上每一个点的前驱.然后我们将最短路上每一条边都标记一次,分别跑一边最短路,求出最短路径即可. 在这我们不用特殊判断是否是 ...
- AC日记——集合位置 洛谷 P1491
集合位置 思路: 次短路: 先走一遍最短路: 记录最短路径,然后依次删边走最短路: 最短的长度就是次短路: 来,上代码: #include <queue> #include <cma ...
- 【洛谷P1491】集合位置
题目大意:求给定的一张无向带权图的次短路. 题解:先跑一遍 spfa 求出从起点到终点的最短路,记录路径.接着枚举删边,并重新跑 spfa,统计最小值即可. 至于为什么 dp 做法不行,暂时还不清楚. ...
- spfa求次短路
思路:先算出每个点到1的最短路d1[i],记录下路径,然后枚举最短路上的边 删掉之后再求一遍最短路,那么这时的最短路就可能是答案. 但是这个做法是错误的,可以被卡掉. 比如根据下面的例题生成的一个数据 ...
- 洛谷 P1466 集合 Subset Sums Label:DP
题目描述 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的.举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,每个子 ...
随机推荐
- CAD指定区域绘制一个jpg文件
主要用到函数说明: _DMxDrawX::DrawToJpg 把指定区域的内容绘制一个jpg文件中.详细说明如下: 参数 说明 BSTR sJpgFilePath Jpg文件名 DOUBLE dLbx ...
- ls 命令还能这么玩?看一下这 20 个实用范例
Linux中一个基本命令是ls.没有这个命令,我们会在浏览目录条目时会遇到困难.这个命令必须被每个学习Linux的人知道. ls是什么 ls命令用于列出文件和目录.默认上,他会列出当前目录的内容.带上 ...
- CodeFrist基础_Fluent Api
一丶首先新建两个实体类 public class Student { public int StudentKey { get; set; } public string StudentName { g ...
- 【Hadoop】四、HDFS的java接口
Hadoop是用java语言实现的,因此HDFS有很好的java接口用以编程,重点就是Hadoop的FileSystem类,它是所有文件系统的抽象类,HDFS实例(DistributedFileS ...
- Linux设置history命令显示行数以及时间
Linux和unix上都提供了history命令,可以查询以前执行的命令历史记录但是,这个记录并不包含时间项目因此只能看到命令,但是不知道什么时间执行的如何让history记录时间呢? 解决方案 注意 ...
- Python学习第二阶段,Day2,import导入模块方法和内部原理
怎样导入模块和导入包?? 1.模块定义:代码越来越多的时候,所有代码放在一个py文件无法维护.而将代码拆分成多个py文件,同一个名字的变量互不影响,模块本质上是一个.py文件或者".py&q ...
- Python selenium chrome打包exe后禁用控制台输出滚动日志
Python selenium chrome打包exe后,在运行的过程中,如果遇到需要input()输入时,会发现被不断滚动刷新的日志把命令行输入快速顶掉了,通过查阅资料不断实践,发现以下方法有效: ...
- 3.2.2.5 BRE运算符优先级
在数学表达式里,正则表达式的运算符具有某种已定义的优先级,指的是某个运算符(优先级较高)将比其他运算符先被处理. BRE运算符优先级,由高至低 运算符 表示含义 [..] [= ...
- 团队开发git使用各种问题
参考:https://www.cnblogs.com/schaepher/p/4933873.html 问题-3:保持github上项目干净,对于在不同机器上运行会不同的文件不予维护(如.idea/w ...
- UVALive 7008 Tactical Multiple Defense System
Tactical Multiple Defense System Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld &a ...