洛谷 P1491 集合位置
题目描述
每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快。还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法永远是'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
思路:K短路,这个题目一样要考虑路是简单路。
错因:
1:数组开的太大;
2:发现代码一个缺陷:A*中第一次tmp入队前,没有把vis置为1;
#include<iostream> #include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 40100 #define INF 0x3f3f3f3f using namespace std; struct nond{ double g,f; int to,vis[MAXN]; bool operator<(const nond &r) const { if(r.f==f) return r.g<g; else return r.f<f; } }tmp,opt; int n,m,s,t,k,cnt,tot,tot1; int x[MAXN],y[MAXN],vis[MAXN]; int to[MAXN],head[MAXN],net[MAXN]; int to1[MAXN],head1[MAXN],net1[MAXN]; double dis[MAXN],cap[MAXN],cap1[MAXN]; void add(int u,int v,double w){ to[++tot]=v;net[tot]=head[u];cap[tot]=w;head[u]=tot; to1[++tot1]=u;net1[tot1]=head1[v];cap1[tot1]=w;head1[v]=tot1; } void spfa(int s){ queue<int>que1; for(int i=0;i<=n;i++) dis[i]=INF; que1.push(s); vis[s]=1;dis[s]=0; while(!que1.empty()){ int now=que1.front(); que1.pop(); vis[now]=0; for(int i=head1[now];i;i=net1[i]) if(dis[to1[i]]>dis[now]+cap1[i]){ dis[to1[i]]=dis[now]+cap1[i]; if(!vis[to1[i]]){ vis[to1[i]]=1; que1.push(to1[i]); } } } } void Astar(){ priority_queue<nond>que; if(s==t) k++; if(dis[s]==INF){ printf("-1"); return; } tmp.g=0; tmp.to=s; tmp.f=dis[s]; tmp.vis[s]=1; que.push(tmp); while(!que.empty()){ tmp=que.top(); que.pop(); if(tmp.to==t) cnt++; if(cnt==k){ printf("%.2lf",tmp.g); return; } for(int i=head[tmp.to];i;i=net[i]){ if(tmp.vis[to[i]]) continue; opt=tmp; opt.to=to[i]; opt.g=tmp.g+cap[i]; opt.f=opt.g+dis[to[i]]; opt.vis[to[i]]=1; que.push(opt); } } printf("-1"); return; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); for(int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); double w=sqrt((x[u]-x[v])*(x[u]-x[v])+(y[u]-y[v])*(y[u]-y[v])); add(u,v,w); add(v,u,w); } s=1;t=n;k=2; spfa(t); Astar(); }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。