生活随笔 
收集整理的這篇文章主要介紹了
                                
迷阵突围 
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
 
                                
                             
                             
                            蒜頭君陷入了坐標系上的一個迷陣,迷陣上有 n 個點,編號從 1 到 n。蒜頭君在編號為 1 的位置,他想到編號為 n 的位置上。蒜頭君當然想盡快到達目的地,但是他覺得最短的路徑可能有風險,所以他會選擇第二短的路徑。現在蒜頭君知道了 n 個點的坐標,以及哪些點之間是相連的,他想知道第二短的路徑長度是多少。  注意,每條路徑上不能重復經過同一個點。
 
輸入格式  第一行輸入兩個整數 n (1≤n≤200) 和 m,表示一共有 n 個點和 m 條邊。  接下來輸入 n 行,每行輸入兩個整數 xi,yi (?500≤xi,yi≤500),代表第 i 個點的坐標。  接下來輸入 m 行,每行輸入兩個整數pj,qj(1≤pj,qj≤n),表示點 pj和點 qj之間相連。
 
輸出格式  輸出一行,輸出包含一個數,表示第二短的路徑長度(小數點后面保留兩位),如果第一短路徑有多條,則答案就是第一最短路徑的長度;如果第二最短路徑不存在,則輸出 ?1。
 
樣例輸入
3  3 
1  1 
2  2 
3  2 
1  2 
2  3 
1  3 
樣例輸出
2.41 
 
這道題可“第K短路”那道題是不同的,這道題要求每條路徑上不能重復經過同一個點,但是“第K短路”那道題沒有這個限制。  這道題的正確做法是在點1到點n的路徑上逐個將邊斷開,求最短路。
 
#include <bits/stdc++.h>  #define  pii pair<int,int> 
#define  dii pair<double,int> 
using  namespace  std
; 
const  int  N 
=  205 ,  M 
=  1e5  +  10 ; 
int  head
[ N
] ,  ver
[ M
] ,  Next
[ M
] ,  tot 
=  1 ; 
double  edge
[ M
] ,  d
[ N
] ; 
int  pre
[ N
] ; 
int  v
[ N
] ; 
vector
< pii 
>  p
; 
int  n
,  m
; inline  void  add ( int  x
,  int  y
,  double  z
)  { ver
[ ++ tot
]  =  y
; edge
[ tot
]  =  z
; Next
[ tot
]  =  head
[ x
] ; head
[ x
]  =  tot
; 
} inline  void  read ( )  { cin 
>>  n 
>>  m
; for  ( int  i 
=  1 ;  i 
<=  n
;  i
++ )  { int  x
,  y
; scanf ( "%d%d" ,  & x
,  & y
) ; p
. emplace_back ( x
,  y
) ; } for  ( int  i 
=  1 ;  i 
<=  m
;  i
++ )  { int  x
,  y
; double  z
; scanf ( "%d%d" ,  & x
,  & y
) ; z 
=  sqrt ( ( p
[ x 
-  1 ] . first 
-  p
[ y 
-  1 ] . first
)  *  ( p
[ x 
-  1 ] . first 
-  p
[ y 
-  1 ] . first
)  + ( p
[ x 
-  1 ] . second 
-  p
[ y 
-  1 ] . second
)  *  ( p
[ x 
-  1 ] . second 
-  p
[ y 
-  1 ] . second
) ) ; add ( x
,  y
,  z
) ; add ( y
,  x
,  z
) ; } 
} void  spfa ( )  { for  ( int  i 
=  2 ;  i 
<=  n
;  i
++ ) d
[ i
]  =  1e9 ,  v
[ i
]  =  0 ; d
[ 1 ]  =  0 ; v
[ 1 ]  =  1 ; queue
< int >  q
; q
. push ( 1 ) ; while  ( ! q
. empty ( ) )  { int  x 
=  q
. front ( ) ; q
. pop ( ) ; v
[ x
]  =  0 ; for  ( int  i 
=  head
[ x
] ;  i
;  i 
=  Next
[ i
] )  { int  y 
=  ver
[ i
] ; double  z 
=  edge
[ i
] ; if  ( d
[ y
]  >  d
[ x
]  +  z
)  { d
[ y
]  =  d
[ x
]  +  z
; pre
[ y
]  =  i
; if  ( ! v
[ y
] )  { v
[ y
]  =  true ; q
. push ( y
) ; } } } } 
} double  dijkstra ( )  { for  ( int  i 
=  1 ;  i 
<=  n
;  i
++ ) d
[ i
]  =  1e9 ,  v
[ i
]  =  0 ; priority_queue
< dii 
>  q
; d
[ 1 ]  =  0 ; q
. push ( { 0 ,  1 } ) ; while  ( ! q
. empty ( ) )  { int  x 
=  q
. top ( ) . second
; q
. pop ( ) ; if  ( v
[ x
] ) continue ; v
[ x
]  =  1 ; for  ( int  i 
=  head
[ x
] ;  i
;  i 
=  Next
[ i
] )  { int  y 
=  ver
[ i
] ; double  z 
=  edge
[ i
] ; if  ( d
[ y
]  >  d
[ x
]  +  z
)  { d
[ y
]  =  d
[ x
]  +  z
; q
. push ( { - d
[ y
] ,  y
} ) ; } } } return  d
[ n
] ; 
} inline  void  solve ( )  { if  ( d
[ n
]  ==  1e9 )  { printf ( "-1" ) ; return ; } int  tc 
=  n
; double  mn 
=  1e9 ; while  ( pre
[ tc
] )  { double  ke 
=  edge
[ pre
[ tc
] ] ; edge
[ pre
[ tc
] ]  =  edge
[ pre
[ tc
]  ^  1 ]  =  1e9 ; mn 
=  min ( mn
,  dijkstra ( ) ) ; edge
[ pre
[ tc
] ]  =  edge
[ pre
[ tc
]  ^  1 ]  =  ke
; tc 
=  ver
[ pre
[ tc
]  ^  1 ] ; } if  ( mn 
>=  1e9 ) printf ( "-1" ) ; else  printf ( "%.2lf" ,  mn
) ; 
} int  main ( )  { read ( ) ; spfa ( ) ; solve ( ) ; return  0 ; 
} 
                            總結 
                            
                                以上是生活随笔 為你收集整理的迷阵突围 的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。