生活随笔
收集整理的這篇文章主要介紹了
HDU 2544 最短路(各种最短路算法的实现)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
鏈接:
http://acm.hdu.edu.cn/showproblem.php?pid=2544
?
題目:
Problem Description
在每年的校賽里,所有進入決賽的同學都會獲得一件很漂亮的t-shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?
? ?
?
Input
輸入包括多組數據。每組數據第一行是兩個整數N、M(N<=100,M<=10000),N表示成都的大街上有幾個路口,標號為1的路口是商店所在地,標號為N的路口是賽場所在地,M則表示在成都有幾條路。N=M=0表示輸入結束。接下來M行,每行包括3個整數A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A與路口B之間有一條路,我們的工作人員需要C分鐘的時間走過這條路。
輸入保證至少存在1條商店到賽場的路線。
? ?
?
Output
對于每組輸入,輸出一行,表示工作人員從商店走到賽場的最短時間
? ?
?
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
? ?
?
Sample Output
3
2
? ?
?
Source
UESTC 6th Programming Contest Online
? ?
?
?
基礎最短路,不解釋,其實是專門用來驗證各種最短路模板的。
在網上搜索的某神的博客,這些模板題其實沒什么來講的,自己再敲一遍和這也差不太遠,圖論的話多看書!
附原文鏈接:?http://blog.csdn.net/shuangde800?
1. ? ?Dijkstra ?普通版
[cpp]?view plaincopy
#include<cstdio>?? #include<cstring>?? const?int?N=105,?INF=9999999;?? int?d[N],?w[N][N],vis[N],n,m;?? void?Dijkstra(int?src){?? ????for(int?i=1;?i<=n;?++i)?? ????????d[i]?=?INF;?? ????d[src]?=?0;??? ????memset(vis,?0,?sizeof(vis));?? ????for(int?i=1;?i<=n;?++i){?? ????????int?u=-1;?? ????????for(int?j=1;?j<=n;?++j)if(!vis[j]){?? ????????????if(u==-1?||?d[j]<d[u])?u=j;?? ????????}?? ????????vis[u]?=?1;?? ????????for(int?j=1;?j<=n;?++j)if(!vis[j]){?? ????????????int?tmp?=?d[u]?+?w[u][j];?? ????????????if(tmp<d[j])?d[j]?=?tmp;?? ????????}?? ????}?? }?? int?main(){?? ????int?a,b,c;?? ????while(~scanf("%d%d",&n,&m)&&n+m){?? ????????for(int?i=1;?i<=n;?++i){?? ????????????w[i][i]?=?INF;?? ????????????for(int?j=i+1;?j<=n;?++j)?? ????????????????w[i][j]?=?w[j][i]?=?INF;?? ????????}?? ????????for(int?i=0;?i<m;?++i){?? ????????????scanf("%d%d%d",&a,&b,&c);?? ????????????w[a][b]?=?w[b][a]?=?c;?? ????????}?? ????????Dijkstra(1);?? ????????printf("%d\n",?d[n]);?? ????}?? ????return?0;?? }?? ?
2. Dijkstra+鄰接表(用數組實現)+優先隊列優化
[cpp]?view plaincopy
#include<cstdio>?? #include<cstring>?? #include<utility>?? #include<queue>?? using?namespace?std;?? const?int?N=20005;?? const?int?INF=9999999;?? typedef?pair<int,int>pii;?? priority_queue<pii,?vector<pii>,?greater<pii>?>q;?? int?d[N],?first[N],?u[N],?v[N],?w[N],?next[N],n,m;?? bool?vis[N];?? //?無向圖的輸入,注意每輸入的一條邊要看作是兩條邊?? void?read_graph(){?? ????memset(first,?-1,?sizeof(first));?//初始化表頭?? ????for(int?e=1;?e<=m;?++e){?? ????????scanf("%d%d%d",&u[e],?&v[e],?&w[e]);?? ????????u[e+m]?=?v[e];?v[e+m]?=?u[e];?w[e+m]?=?w[e];??//?增加一條它的反向邊?? ????????next[e]?=?first[u[e]];??//?插入鏈表?? ????????first[u[e]]?=?e;?? ????????next[e+m]?=first[u[e+m]];?//?反向邊插入鏈表?? ????????first[u[e+m]]?=?e+m;?? ????}?? }?? void?Dijkstra(int?src){?? ????memset(vis,?0,?sizeof(vis));?? ????for(int?i=1;?i<=n;?++i)?d[i]?=?INF;?? ????d[src]?=?0;?? ????q.push(make_pair(d[src],?src));?? ????while(!q.empty()){?? ????????pii?u?=?q.top();?q.pop();?? ????????int?x?=?u.second;?? ????????if(vis[x])?continue;?? ????????vis[x]?=?true;?? ????????for(int?e?=?first[x];?e!=-1;?e=next[e])?if(d[v[e]]?>?d[x]+w[e]){?? ????????????d[v[e]]?=?d[x]?+?w[e];?? ????????????q.push(make_pair(d[v[e]],?v[e]));?? ????????}??? ????}?? }?? int?main(){?? ????int?a,b,c;?? ????while(~scanf("%d%d",&n,&m)&&n+m){?? ????????read_graph();?? ????????Dijkstra(1);?? ????????printf("%d\n",?d[n]);?? ????}?? ????return?0;?? }?? ?
3. Dijkstra+鄰接表(用vecor實現)+優先隊列優化
[cpp]?view plaincopy
#include<cstdio>?? #include<cstring>?? #include<utility>?? #include<queue>?? #include<vector>?? using?namespace?std;?? const?int?N=105;?? const?int?INF=9999999;?? typedef?pair<int,int>pii;?? vector<pii>G[N];?? priority_queue<pii,?vector<pii>,?greater<pii>?>q;?? int?d[N],?first[N],?u[N],?v[N],?w[N],?next[N],n,m;?? bool?vis[N];?? //?無向圖的輸入,注意沒輸入的一條邊要看作是兩條邊?? void?read_graph(){?? ????for(int?i=1;?i<=n;?++i)?? ????????G[i].clear();?? ????int?a,b,c;?? ????for(int?i=1;?i<=m;?++i){?? ????????scanf("%d%d%d",&a,&b,&c);?? ????????G[a].push_back(make_pair(b,c));?? ????????G[b].push_back(make_pair(a,c));?? ????}?? }?? void?Dijkstra(int?src){?? ????memset(vis,?0,?sizeof(vis));?? ????for(int?i=1;?i<=n;?++i)?d[i]?=?INF;?? ????d[src]?=?0;?? ????q.push(make_pair(d[src],?src));?? ????while(!q.empty()){?? ????????pii?t?=?q.top();?q.pop();?? ????????int?u?=?t.second;?? ????????if(vis[u])?continue;?? ????????vis[u]?=?true;?? ????????for(int?v=0;?v<G[u].size();?++v)if(d[G[u][v].first]?>?d[u]+G[u][v].second){?? ????????????d[G[u][v].first]?=?d[u]+G[u][v].second;?? ????????????q.push(make_pair(d[G[u][v].first],?G[u][v].first));?? ????????}?? ????}?? }?? int?main(){?? ????int?a,b,c;?? ????while(~scanf("%d%d",&n,&m)&&n+m){?? ????????read_graph();?? ????????Dijkstra(1);?? ????????printf("%d\n",?d[n]);?? ????}?? ????return?0;?? }?? ?
?
二,Bellman-Ford算法
[cpp]?view plaincopy
#include<cstdio>?? #include<cstring>?? #include<utility>?? #include<queue>?? using?namespace?std;?? const?int?N=20005;?? const?int?INF=9999999;?? int?n,?m,?u[N],v[N],w[N],?d[N];?? //?無向圖的輸入,注意每輸入的一條邊要看作是兩條邊?? inline?void?read_graph(){?? ????for(int?e=1;?e<=m;?++e){?? ????????scanf("%d%d%d",&u[e],&v[e],&w[e]);?? ????}?? }?? inline?void?Bellman_Ford(int?src){?? ????for(int?i=1;?i<=n;?++i)?d[i]?=?INF;?? ????d[src]?=?0;?? ????for(int?k=0;?k<n-1;?++k){?? ????????for(int?i=1;?i<=m;?++i){??? ????????????int?x=u[i],?y=v[i];?? ????????????if(d[x]?<?INF){?? ????????????????if(d[y]>d[x]+w[i])?? ????????????????????d[y]?=?d[x]+w[i];?? ????????????}?? ????????????if(d[y]?<?INF){?? ????????????????if(d[x]>d[y]+w[i])?? ????????????????????d[x]?=?d[y]+w[i];?? ????????????}?? ????????}?? ????}?? }?? int?main(){?? ????int?a,b,c;?? ????while(~scanf("%d%d",&n,&m)&&n+m){?? ????????read_graph();?? ????????Bellman_Ford(1);?? ????????printf("%d\n",?d[n]);?? ????}?? ????return?0;?? }?? ?
三,SPFA
鄰接表實現
[cpp]?view plaincopy
#include<cstdio>?? #include<cstring>?? #include<utility>?? #include<queue>?? using?namespace?std;?? const?int?N=20005;?? const?int?INF=2147483646>>1;?? int?n,?m,?first[N],next[N],u[N],v[N],w[N],?d[N];?? bool?vis[N];?? queue<int>q;?? inline?void?read_graph(){?? ????memset(first,?-1,?sizeof(first));?? ????for(int?e=1;?e<=m;?++e){?? ????????scanf("%d%d%d",&u[e],&v[e],&w[e]);?? ????????u[e+m]=v[e],?v[e+m]=u[e],?w[e+m]=w[e];?? ????????next[e]?=?first[u[e]];?? ????????first[u[e]]?=?e;?? ????????next[e+m]?=?first[u[e+m]];?? ????????first[u[e+m]]?=?e+m;?? ????}?? }?? void?SPFA(int?src){?? ????memset(vis,?0,?sizeof(vis));?? ????for(int?i=1;?i<=n;?++i)?d[i]?=?INF;?? ????d[src]?=?0;?? ????vis[src]?=?true;?? ????q.push(src);?? ????while(!q.empty()){?? ????????int?x?=?q.front();??q.pop();?? ????????vis[x]?=?false;?? ????????for(int?e=first[x];?e!=-1;?e=next[e]){?? ????????????if(d[x]+w[e]?<?d[v[e]]){?? ????????????????d[v[e]]?=?d[x]+w[e];?? ????????????????if(!vis[v[e]]){?? ????????????????????vis[v[e]]?=?true;?? ????????????????????q.push(v[e]);?? ????????????????}?? ????????????}?? ????????}?? ????}??? }?? int?main(){?? ????int?a,b,c;?? ????while(~scanf("%d%d",&n,&m)&&n+m){?? ????????read_graph();?? ????????SPFA(1);?? ????????printf("%d\n",?d[n]);?? ????}?? ????return?0;?? }?? ?
?
四, Floyd算法
[cpp]?view plaincopy
#include<cstdio>?? #include<cstring>?? #include<utility>?? #include<queue>?? using?namespace?std;?? const?int?N=105;?? const?int?INF=2147483646;?? int?n,?m,?d[N][N];?? inline?void?read_graph(){?? ????for(int?i=1;?i<=n;?++i){?? ????????d[i][i]?=?INF;?? ????????for(int?j=i+1;?j<=n;?++j)?? ????????????d[i][j]=d[j][i]=INF;?? ????}?? ????int?a,b,c;?? ????for(int?e=1;?e<=m;?++e){?? ????????scanf("%d%d%d",&a,&b,&c);?? ????????d[a][b]=d[b][a]=c;?? ????}?? }?? inline?void?Floyd(int?src){?? ????for(int?k=1;?k<=n;?++k){?? ????????for(int?i=1;?i<=n;?++i){?? ????????????for(int?j=1;?j<=n;?++j)?? ????????????????if(d[i][k]<INF?&&?d[k][j]<INF){??//防止溢出?? ????????????????????d[i][j]?=?min(d[i][j],?d[i][k]+d[k][j]);?? ????????????????}?? ????????}?? ????}?? }?? int?main(){?? ????int?a,b,c;?? ????while(~scanf("%d%d",&n,&m)&&n+m){?? ????????read_graph();?? ????????Floyd(1);?? ????????printf("%d\n",?d[1][n]);?? ????}?? ????return?0;?? }??
總結
以上是生活随笔為你收集整理的HDU 2544 最短路(各种最短路算法的实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。