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}能划分成两个子集合,每个子 ...
随机推荐
- WebService接口数据传输加密
1.加密流程 客服端--->加密文本------>服务端接收到加密文本,通过固定加密密文进行解密,然后做相应处理------------>返回结果 2.固定密文创建 密文创建有很多种 ...
- 洛谷——P1349 广义斐波那契数列(矩阵加速)
P1349 广义斐波那契数列 题目描述 广义的斐波那契数列是指形如$an=p\times a_{n-1}+q\times a_{n-2}$?的数列.今给定数列的两系数$p$和$q$,以及数列的最前两项 ...
- [Luogu] P3258 [JLOI2014]松鼠的新家
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...
- Python,socket编程
TCP协议 IP+端口 应用层协议做的事不同,但都离不开数据的交换,本质上都是收和发~为什么要三次握手?目标机器可能不存在,握手期间,发送方也可能down掉.客户端————服务器,先发请求的那个是客户 ...
- 3.2.3.7 ERE 运算符的优先级
在 ERE 里运算符的优先级和 BRE 一样.由高至低列出了 ERE 运算符的优先级. 运算符 含义 [..] [= =] [: :] 用于字符对应的方括号符号 \metachar ...
- cmd界面中断一个程序快捷键 ctrl+c
cmd界面中断一个程序快捷键 ctrl+c
- [POJ3162]Walking Race(DP + 单调队列)
传送门 题意:一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离 ...
- Codeforces Round #232 (Div. 2) C
C. On Number of Decompositions into Multipliers time limit per test 1 second memory limit per test 2 ...
- loginitem
+ (BOOL) willStartAtLogin:(NSURL *)itemURL { Boolean foundIt=false; LSSharedFileListRef loginItems = ...
- 这个贴子的内容值得好好学习--实例详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化
感觉要DJANGO用得好,ORM必须要学好,不管理是内置的,还是第三方的ORM. 最最后还是要到SQL.....:( 这一关,慢慢练啦.. 实例详解Django的 select_related 和 p ...