集合位置

集合位置

时间限制: 1 Sec  内存限制: 128 MB
提交: 33  解决: 12
[提交][状态][讨论版]

题目描述

  每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快。还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法永远是'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。

样例输入

3 3
0 0
1 1
0 2
1 2
1 3
2 3

样例输出

2.83

题解:用dijkstra求出最短路的解,然后枚举删除边,删的是最短路的边,否则若最短路存在则最短路最短,找不出第二短的边,
每次用spfa求最短路,然后求出第二短的路即可。
  1 #include<cstdio> 
  2 #include<cstring> 
  3 #include<queue> 
  4 #include<vector> 
  5 #include<cmath> 
  6 #include<algorithm> 
  7 using namespace std; 
  8 const int MAXN=205; 
  9 const double INF=100000000.0; 
 10 typedef pair<int,double> P; 
 11 struct Node{ 
 12     int x,y; 
 13 }pos[MAXN]; 
 14 struct Edge{ 
 15     int to; 
 16     double w; 
 17     Edge(int to,double w) 
 18     { 
 19         this->to=to; 
 20         this->w=w; 
 21     } 
 22 }; 
 23 int pre[MAXN]; 
 24 vector<Edge> mp[MAXN]; 
 25 double dist(int x,int y,int x1,int y1) 
 26 { 
 27     return sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1)); 
 28 } 
 29 int n,m; 
 30 double d[MAXN]; 
 31 void dijkstra(int s) 
 32 { 
 33     for(int i=1;i<=n;i++) 
 34     { 
 35         d[i]=INF; 
 36     } 
 37     d[s]=0; 
 38     priority_queue<P,vector<P>,greater<P> > que; 
 39     que.push(P(0,s)); 
 40       
 41     while(!que.empty()) 
 42     { 
 43         P now=que.top();
 44         que.pop(); 
 45         int u=now.second; 
 46         if(d[u]<now.first) continue; 
 47         for(int i=0;i<mp[u].size();i++) 
 48         { 
 49             Edge e=mp[u][i]; 
 50             if(d[e.to]>d[u]+e.w) 
 51             { 
 52                 d[e.to]=d[u]+e.w; 
 53                 pre[e.to]=u; 
 54                 que.push(P(d[e.to],e.to)); 
 55             } 
 56         }     
 57     } 
 58 } 
 59 double d1[MAXN]; 
 60 int vis[MAXN]; 
 61 void spfa(int s,int u,int v) 
 62 { 
 63     for(int i=1;i<=n;i++) 
 64     { 
 65         d1[i]=INF; 
 66         vis[i]=0; 
 67     } 
 68       
 69     queue<int> que; 
 70     que.push(s); 
 71     d1[s]=0; 
 72     vis[s]=1; 
 73     while(!que.empty()) 
 74     { 
 75         int now=que.front();que.pop(); 
 76         vis[now]=0; 
 77         for(int i=0;i<mp[now].size();i++) 
 78         { 
 79             Edge e=mp[now][i]; 
 80             if((now==u&&e.to==v)||(now==v&&e.to==u)) 
 81                 continue; 
 82             if(d1[e.to]>d1[now]+e.w) 
 83             { 
 84                 d1[e.to]=d1[now]+e.w; 
 85                 if(!vis[e.to]) 
 86                 { 
 87                     vis[e.to]=1; 
 88                     que.push(e.to); 
 89                 } 
 90             } 
 91         } 
 92     } 
 93 } 
 94   
 95 int main() 
 96 { 
 97       
 98     scanf("%d%d",&n,&m); 
 99     for(int i=1;i<=n;i++) 
100     { 
101         scanf("%d%d",&pos[i].x,&pos[i].y); 
102     } 
103     for(int i=1;i<=m;i++) 
104     { 
105         int u,v; 
106         scanf("%d%d",&u,&v); 
107         double w=dist(pos[u].x,pos[u].y,pos[v].x,pos[v].y); 
108         mp[u].push_back(Edge(v,w)); 
109         mp[v].push_back(Edge(u,w)); 
110           
111     }
112     
113     dijkstra(1); 
114       
115     double mn=INF; 
116     int pr=n; 
117     while(pre[pr]!=0) 
118     {
119         spfa(1,pr,pre[pr]); 
120         mn=min(mn,d1[n]); 
121         pr=pre[pr]; 
122     }
123       
124     if(fabs(mn-INF)<0.000001) 
125         printf("-1
"); 
126     else
127         printf("%.2f
",mn); 
128 } 
View Code

原文地址:https://www.cnblogs.com/fengzhiyuan/p/6977798.html