説明[タイトル]
n点(n≤100)面があり、各点の座標は、-10000〜10000の間です。それらの間の接続ポイントがいくつかあります。
接続した場合、その後、一点から別の点への2つの点、二点間の直線経路距離の距離との間の経路に到達することができます。タスクは現在、別のポイントからの最短経路を見つけることです。
[Enter]を
総計N + M + 3行、ここで:
最初の行の整数n。
(n行の)行に行2 N + 1、各行2つの整数xとyは、点の座標が記載されています。
整数n + 2メートルの挙動は、図は、接続の数を表します。
m行の後に、各列iおよびjはなる二つの整数の接続を記述し、i番目とj番目の点の間の接続点を発現しました。
最後の行の2つの整数sおよびtは、それぞれ、ソースおよび宛先点を表します。
[出力]
ラインは、実数(小数点以下)は、SからTへの最短経路の長さを表します。
[サンプル入力]
5 0 0 2 0 2 2 0 2 3 1 5 1 2 1 3 1 4 2 5 3 10 1 5
[サンプル出力]
3.41
1. Floyed-ウォーシャルアルゴリズムは、O(N3)、N <= 500
1つの#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 INT [ 101 ] [ 3 ]、N、I、J、K、X、Y、M、S、E。 4 ダブル F [ 101 ] [ 101 ]。 5 INT メイン() 6 { 7 CIN >> N。 8 のためには、(i = 1 ; iが<= N; iは++ ) 9 >> CINを[I] [ 1 ] >> [I] [ 2 ]。 // 第I个点的坐标 10 cinを>> メートル。 11 memsetの(F、は0x3F、はsizeof(F)); //はfが最大値に配列を初期化 12である ため(I = 1 ; I <= M、Iは++) // xの前処理、Yの間の距離 13は、 { 14 >> CIN Y >> X; // POW(x、y)は^ Y、式中、X、Xを表し、Yは二重型である必要があり、使用cmathライブラリ 15 F [Y] [X] = F [X] [Y]は(SQRTを= POW(ダブル([X] [ 1。 -a [Y] [] 1。 ])、2)+ POW(ダブル([X] [ 2 ] -a [Y] [ 2 ])、2 )); 16 } 17 CIN >> S >> E。 18 のための(K = 1 ; K <= N; kは++) // 最短路算法floyed 19 用(i = 1 ; I ++; iが= N < ) 20 用(J = 1 ; J <= N; J ++ ) 21 場合を((I!= J)&&(I!= K)&&(j!= K)&&([I] [K] + F [k]は[J] <F F [I] [J])) 22 F [I] [J] = F [i]が[K] + F [k]は[J]。 23 のprintf(" %.2lfする\ n " F、[S] [E])。 24 リターン 0 ; 25 }
2. ダイクストラアルゴリズムは O(N2)非最適化N <= 5000貪欲
1つの#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 int型 [ 101 ] [ 3 ]、F [ 101 ] [ 101 ] ;; 4 二重 C [ 101 ]。 5 ブール B [ 101 ]。 6 INTのN、I、J、K、X、Y、M、S、E。 7 ダブルminl。 8 ダブル MAXX = 1e30。 9 INT メイン() 10 { 11 CIN >> N。 12 のための(I = 1;私は= N- <; Iを++ ) 13である [CIN >> A [I] 。1 ] >> A [I] [ 2 。] 14 のため =(I 1、I <= N; I ++ ) 15 用(J = 1。 J <= N; J ++ ) 16 F [I] [J] =マックス; // F最大アレイの初期化 。17 CIN >> M、 18である ため(I = 1 ; I <= M、Iは++) // 前処理XY F間の距離[X] [Y] 19。 { 20は CIN >> X Y、 21は F [X] [Y] = F [Y] [X] = SQRT(POW(二重([X] [ 1 ] -a [Y] [ 1 ])、2)+ POW(ダブル([X] [ 2 ] -a [Y] [ 2 ])、2 ))。 22 } 23 CIN >> S >> E。 24 のためには、(i = 1 ; iが<= N; iは++ ) 25の Cを[I] = F [S] [I]。 // 初始化 26 のmemset(B、偽、はsizeof(b)参照)。 // ダイクストラ最短路 27 (b)は、[S] = 真。 //ソースポイント 28 C [S] = 0 ; 29 のための(I = 1 ; I <= N- 1、I ++は) 30 { 31が minL =マックス; // 貪欲最小見つける 32 K = 0 、 33である ため(Jは= 1 ; J <= N; J ++) // 更新することができる点を探し 34は IF(!(B [J])&&(C [J] < minL)) 35 { 36 minL = C [J]; 37 [ K = J、 38であります } 39 もし(K == e)のブレーク。 // 小优化 40 B [k]は= 真。 41 のために(J = 1 ; J <= N; J ++ ) 42 であれば(C [K] + F [k]は[J] < C [J]) 43個の C [J] = Cの[K] + F [K] [J]。 44 } 45 のprintf(" %.2lfする\ n " 、C [E])。 46 リターン 0 ; 47 }
最適化されたスタック後ダイクストラアルゴリズムは O(NlogN)
ため(I = 1 ; I <= N- 1、Iは++ ) { minL = マックス; K = 0 ; のため(Jは= 1。 ; J <= N; J ++)//の外観はポイントを更新することができる IF((Bの[! J])&&(C [J] < minL)) { minL = C [J]; K = J; } IF(K == E)BREAK ; B [K]は = trueに、 ため(Jは= 1。; J <= N。J ++ ) 場合(C [K] + F [k]は[J] < C [J]) C [J] = Cの[K] + F [k]は[J]。 }
最適隣接テーブルプラスヒープ
別の機能も付与することができます
3. ベルマン-フォード法は O(NE)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 double a[101][3],dis[1001],w[1001],min1; 6 int n,m,x,y,k,f[1001][3],s,t; // f数组储存第i条边的起点与终点 7 bool b[101]; 8 cin>>n; 9 for (int i=1;i<=n;i++) 10 scanf("%lf%lf",&a[i][1],&a[i][2]); 11 cin>>m; 12 for (int i=1;i<=m;i++) //初始化数组dis 13 dis[i]=0x7fffffff/3; 14 for (int i=1;i<=m;i++) 15 { 16 scanf("%d%d",&x,&y); 17 f[i][1]=x; f[i][2]=y; 18 w[i]=sqrt(pow(a[x][1]-a[y][1],2)+pow(a[x][2]-a[y][2],2)); 19 } 20 cin>>s>>t; 21 dis[s]=0; 22 for (int i=1;i<=n;i++) //ford算法主体 23 for (int j=1;j<=m;j++) 24 { 25 if (dis[f[j][1]]+w[j]<dis[f[j][2]]) dis[f[j][2]]=dis[f[j][1]]+w[j]; 26 if (dis[f[j][2]]+w[j]<dis[f[j][1]]) dis[f[j][1]]=dis[f[j][2]]+w[j]; 27 } 28 printf("%.2f",dis[t]); 29 }
4、SPFA算法O(kE)