题目描述
每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快。还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法永远是'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。
输入输出样例
说明
各个测试点1s
分析:开始在网上看到了一个Dijkstra算法一次性求最短路和次短路,然后决定来拿这题练手,结果...感人肺腑的卡了两个小时,死活有两个点会wa掉。最后没办法就索性打了个暴力spfa+删边。。。然后之前那个还没调对。。。两份代码都放一下吧。
Code:
(Dijkstra)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=407; 4 #define INF 2e9+7 5 typedef pair<double,int>P; 6 int n,m; 7 double di[N][N],dis[N],dist[N]; 8 struct pos{int x,y;}a[N]; 9 struct node{ 10 int to;double val; 11 node(int x=0,double y=0): 12 to(x),val(y){}}; 13 vector<node>g[N]; 14 void dijkstra() 15 { 16 priority_queue<P, vector<P>, greater<P> >team; 17 fill(dis,dis+N,INF); 18 fill(dist,dist+N,INF); 19 dis[1]=0; 20 team.push(P(0,1)); 21 while(!team.empty()){ 22 P p=team.top();team.pop(); 23 int x=p.second; 24 double d=p.first; 25 if(dist[x]<d)continue; 26 for(int i=0;i<g[x].size();i++){ 27 node e=g[x][i]; 28 double dt=d+e.val; 29 if(dis[e.to]>dt){ 30 swap(dis[e.to],dt); 31 team.push(P(dis[e.to],e.to)); 32 } 33 if(dist[e.to]>dt&&dis[e.to]<dt){ 34 dist[e.to]=dt; 35 team.push(P(dist[e.to],e.to)); 36 } 37 } 38 } 39 if(dist[n]<dist[0]) 40 printf("%.2lf",dist[n]); 41 else 42 printf("-1"); 43 } 44 double get(int A,int B) 45 { 46 double x1=a[A].x*1.0,y1=a[A].y*1.0; 47 double x2=a[B].x*1.0,y2=a[B].y*1.0; 48 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 49 } 50 int main() 51 { 52 scanf("%d%d",&n,&m); 53 int x,y; 54 for(int i=1;i<=n;i++) 55 scanf("%d%d",&a[i].x,&a[i].y); 56 for(int i=1;i<n;i++) 57 for(int j=i+1;j<=n;j++) 58 di[i][j]=di[j][i]=get(i,j); 59 for(int i=1;i<=m;i++){ 60 scanf("%d%d",&x,&y); 61 g[x].push_back(node{y,di[x][y]}); 62 g[y].push_back(node{x,di[y][x]});} 63 dijkstra(); 64 return 0; 65 }
(SPFA+删边)
1 #include<bits/stdc++.h> 2 #define Fi(a,b,c) for(int a=b;a<=c;a++) 3 #define Fx(a,b,c) for(int a=b;a>=c;a--) 4 using namespace std; 5 const int N=2007; 6 int n,m,head[N],size,pre[N]; 7 double d[N][N],dis[N],ans; 8 bool vis[N]; 9 struct Poi{int x,y;}a[N]; 10 struct Node{ 11 int to,next;double val; 12 }edge[N<<5]; 13 inline int read() 14 { 15 char ch=getchar();int num=0;bool flag=false; 16 while(ch<'0'||ch>'9'){if(ch=='-')flag=true;ch=getchar();} 17 while(ch>='0'&&ch<='9'){num=num*10+ch-'0';ch=getchar();} 18 return flag?-num:num; 19 } 20 inline void add(int x,int y,double z) 21 { 22 edge[++size].to=y; 23 edge[size].val=z; 24 edge[size].next=head[x]; 25 head[x]=size; 26 } 27 inline double get(int x,int y) 28 { 29 double x1=a[x].x*1.0,y1=a[x].y*1.0; 30 double x2=a[y].x*1.0,y2=a[y].y*1.0; 31 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 32 } 33 void spfa() 34 { 35 memset(vis,false,sizeof(vis)); 36 Fi(i,1,n)dis[i]=0x3f3f3f3f; 37 queue<int>team;team.push(1); 38 dis[1]=0;vis[1]=true; 39 while(!team.empty()){ 40 int x=team.front();team.pop();vis[x]=false; 41 for(int i=head[x];i!=-1;i=edge[i].next){ 42 int y=edge[i].to; 43 if(dis[y]>dis[x]+edge[i].val){ 44 dis[y]=dis[x]+edge[i].val;pre[y]=x; 45 if(!vis[y]){team.push(y);vis[y]=true;}}}} 46 } 47 inline double SPFA(int u,int v) 48 { 49 memset(vis,false,sizeof(vis)); 50 Fi(i,1,n)dis[i]=0x3f3f3f3f; 51 queue<int>team;team.push(1); 52 dis[1]=0;vis[1]=true; 53 while(!team.empty()){ 54 int x=team.front();team.pop();vis[x]=false; 55 for(int i=head[x];i!=-1;i=edge[i].next){ 56 int y=edge[i].to;if((x==u&&y==v)||(x==v&&y==u))continue; 57 if(dis[y]>dis[x]+edge[i].val){ 58 dis[y]=dis[x]+edge[i].val; 59 if(!vis[y]){team.push(y);vis[y]=true;}}}} 60 return dis[n]; 61 } 62 int main() 63 { 64 n=read();m=read(); 65 memset(head,-1,sizeof(head)); 66 Fi(i,1,n)a[i].x=read(),a[i].y=read(); 67 Fi(i,1,n-1) Fi(j,i+1,n) 68 d[i][j]=d[j][i]=get(i,j); 69 Fi(i,1,m){int x=read();int y=read(); 70 add(x,y,d[x][y]);add(y,x,d[y][x]);} 71 spfa();ans=0x3f3f3f3f;int f=n; 72 while(555){ 73 double ka=SPFA(pre[f],f); 74 if(ans>ka)ans=ka;f=pre[f]; 75 if(f==1)break;} 76 if(ans>999999)printf("-1"); 77 else printf("%.2lf",ans); 78 return 0; 79 }