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控件:COM接口实现自定义实体
1. 实现步骤: 3 1. 实现步骤: 参考例子 :Src\MxDraw5.2\samples\ie\iedemoTest.htm 1) 增加自定义实体对象 调用DrawCustomEntity函数, ...
- Java怎么实现文件数据拷贝
实现一个文件的内容拷贝到另一个文件里 public void copyDemo () throws IOException { //创建文件输入流 FileInputStream fis = new ...
- Ansible基于playbook批量修改主机名实战
Ansible基于playbook批量修改主机名 安装Ansible,相信这里也不用多说,大家都知道 说一下环境:这里的主机名是修改之后的,我先把其他两台的主机名改为别的 192.168.30.21 ...
- SIGFPE能处理上下溢吗?
SIGFPE可以报告算术异常.包括上下溢.除零等. C标准库说: 各种实现报告的异常类型区别也很大,但几乎没有实现会报告整型溢出. 真的吗?我测试了一下,发现在GCC上,整型.浮点上下溢都不会报告,但 ...
- HDU4496 D-City【基础并查集】
Problem Description Luxer is a really bad guy. He destroys everything he met. One day Luxer went to ...
- 斯特林公式 hdu1018
杭电上面1018>>点击测试<< 思路:当问到阶乘的值时候,用万进制来写:但是问阶乘值的位数的时候,就可以用斯特林公式了 log10(2*pi*n)/2+n*log10(n/e ...
- Delphi语法
类与对象 从用户角度考虑,用户并不需要了解面向对象编程的知识,就可编写Delphi应用程序.当用户在建立新窗体.添加新组件以及处理事件时,大部分相关代码会由Delphi自动产生.但是,知道语言及其细节 ...
- Navigator的学习
Navigator 对象包含有关浏览器的信息.注释:没有应用于 navigator 对象的公开标准,不过所有浏览器都支持该对象. 我感觉需要看什么属性和方法,直接输出这个navigator,然 ...
- ansible playbooks loop循环
在一个task中循环某个操作 1.标准循环 - name: add several users user: name: "{{ item }}" state: present gr ...
- hdu 2094拓扑排序map实现记录
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #i ...