HDU-1874 畅通工程续 (最短路径启蒙题)
???????hdu 1874比較基礎(chǔ),拿來練各種剛學會的算法比較好,可以避免好多陷阱,典型的最短路模板題????????????????????????????????
?????????????? ? 暢通工程續(xù)
Time Limit: 3000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 21028????Accepted Submission(s): 7310
Problem Description 某省自從實行了很多年的暢通工程計劃后,終于修建了很多路。不過路多了也不好,每次要從一個城鎮(zhèn)到另一個城鎮(zhèn)時,都有許多種道路方案可以選擇,而某些方案要比另一些方案行走的距離要短很多。這讓行人很困擾。現(xiàn)在,已知起點和終點,請你計算出要從起點到終點,最短需要行走多少距離。 Input 本題目包含多組數(shù)據(jù),請?zhí)幚淼轿募Y(jié)束。 每組數(shù)據(jù)第一行包含兩個正整數(shù)N和M(0<N<200,0<M<1000),分別代表現(xiàn)有城鎮(zhèn)的數(shù)目和已修建的道路的數(shù)目。城鎮(zhèn)分別以0~N-1編號。 接下來是M行道路信息。每一行有三個整數(shù)A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城鎮(zhèn)A和城鎮(zhèn)B之間有一條長度為X的雙向道路。 再接下一行有兩個整數(shù)S,T(0<=S,T<N),分別代表起點和終點。 Output 對于每組數(shù)據(jù),請在一行里輸出最短需要行走的距離。如果不存在從S到T的路線,就輸出-1. Sample Input 3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2 Sample Output 2 -1 Author linle Source 2008浙大研究生復試熱身賽(2)——全真模擬 Recommend lcy 第一種解法:Floyd算法
算法實現(xiàn): 使用一個鄰接矩陣存儲邊權(quán)值,兩兩之間能訪問的必為一個有限的數(shù),不能訪問則為無窮大(用2^29代替)。注意自身和自身距離為0。 對于一對頂點 u 和 v,看看是否存在一個斷點 w 使得從 u 經(jīng)過 w 到 v 比已知的路徑更短(包含原始輸入中從 u 直接到 v 的路程)。 對所有頂點進行如上松弛操作,得到的結(jié)果是兩點之間的最短路程,也可判斷兩點是否連通。 算法缺點:
普通的Floyd算法時間復雜度為O(n^3),對于數(shù)據(jù)較多的情況容易TLE。但解決本題 HDU 1874 完全足夠。
1 #include<stdio.h> 2 # define max 0xfffffff//定義最大的數(shù)。 3 int n,m,map[201][201]; 4 int min(int x,int y) 5 { 6 return x>y?y:x; 7 } 8 void getmap()//初始化路徑。 9 { 10 int i,j,a,b,l; 11 for(i=0;i<n;i++) 12 { 13 for(j=0;j<n;j++) 14 { 15 if(i==j) 16 map[i][j]=0; 17 else 18 map[i][j]=max; 19 } 20 } 21 for(i=0;i<m;i++) 22 { 23 scanf("%d%d%d",&a,&b,&l); 24 map[a][b]=map[b][a]=min(map[a][b],l);//題目是雙向路徑還是單向路徑, 25 } 26 27 } 28 void floyd(int s,int e) 29 { 30 int i,j,k; 31 for(k=0;k<n;k++) 32 for(i=0;i<n;i++) 33 for(j=0;j<n;j++) 34 map[i][j]=min(map[i][j],map[i][k]+map[k][j]);//注意k,i,j的順序不能換。 35 if(map[s][e]>=max) 36 printf("-1\n"); 37 else 38 printf("%d\n",map[s][e]); 39 } 40 int main() 41 { 42 int s,e; 43 while(~scanf("%d%d",&n,&m)) 44 { 45 getmap(); 46 scanf("%d%d",&s,&e); 47 floyd(s,e); 48 } 49 return 0; 50 }第二種解法:Dijkstra算法, 我對于這種算法還不太熟悉。
?
這個算法比較經(jīng)典,一般的最短路徑都可以用這個來解決,耗時也比較少,不過不能處理負權(quán)路徑
按路徑長度遞增次序產(chǎn)生最短路徑算法:
把V分成兩組:
(1)S:已求出最短路徑的頂點的集合
(2)V-S=T:尚未確定最短路徑的頂點集合
將T中頂點按最短路徑遞增的次序加入到S中,
保證:(1)從源點V0到S中各頂點的最短路徑長度都不大于
從V0到T中任何頂點的最短路徑長度
(2)每個頂點對應一個距離值
S中頂點:從V0到此頂點的最短路徑長度
T中頂點:從V0到此頂點的只包括S中頂點作中間
頂點的最短路徑長度
依據(jù):可以證明V0到T中頂點Vk的最短路徑,或是從V0到Vk的
直接路徑的權(quán)值;或是從V0經(jīng)S中頂點到Vk的路徑權(quán)值之和
(反證法可證)
求最短路徑步驟
算法步驟如下:
1. 初使時令 S={V0},T={其余頂點},T中頂點對應的距離值
若存在<V0,Vi>,d(V0,Vi)為<V0,Vi>弧上的權(quán)值
若不存在<V0,Vi>,d(V0,Vi)為∝
2. 從T中選取一個其距離值為最小的頂點W且不在S中,加入S
3. 對T中頂點的距離值進行修改:若加進W作中間頂點,從V0到Vi的
距離值比不加W的路徑要短,則修改此距離值
重復上述步驟2、3,直到S中包含所有頂點,即S=T為止
?
轉(zhuǎn)載于:https://www.cnblogs.com/cancangood/p/3293104.html
總結(jié)
以上是生活随笔為你收集整理的HDU-1874 畅通工程续 (最短路径启蒙题)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux select TCP并发服务
- 下一篇: 配置纯净版Debian