一、Dijkstra算法
问题一:
输入:
6 8 0
0 1 1
0 3 4
0 4 4
1 3 2
2 5 1
3 2 2
3 4 3
4 5 3
输出:
0 1 5 3 4 6
代码:
(1)邻接矩阵
#include<iostream> #include<algorithm> #include<queue> #include<cstdio> #include<cstdlib> #include<cstring> using namespace std; #define maxn 100 #define INF 0x3f3f3f3f void dij(int s); int n,m,s; int G[maxn][maxn],d[maxn]; bool vis[maxn]={false}; int main(){ cin>>n>>m>>s; memset(G,INF,sizeof(G)); for(int i=0;i<m;i++){ int x,y,z; cin>>x>>y>>z; G[x][y]=z; } dij(s); for(int i=0;i<n;i++){ cout<<d[i]<<" "; } cout<<endl; return 0; } void dij(int s){ memset(d,INF,sizeof(d)); d[s] = 0; for(int i=0;i<n;i++){ int u = -1,MIN = INF; for(int j=0;j<n;j++){ if(vis[j]==false&&d[j]<MIN){ u = j; MIN = d[j]; } } if(u==-1){ return; } vis[u] = true; for(int v=0;v<n;v++){ if(vis[v]==false&&G[u][v]!=INF&&d[u]+G[u][v]<d[v]){ d[v] = d[u]+G[u][v]; } } } }
(2)邻接表
#include<iostream> #include<algorithm> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> using namespace std; #define maxn 100 #define INF 0x3f3f3f3f struct node{ int v,vis; }; void dij(int s); int n,m,s; int d[maxn]; vector<node> adj[maxn]; bool vis[maxn]={false}; int main(){ cin>>n>>m>>s; for(int i=0;i<n;i++){ adj[i].clear(); } for(int i=0;i<m;i++){ int x,y,z; cin>>x>>y>>z; node temp; temp.v = y; temp.vis = z; adj[x].push_back(temp); } dij(s); for(int i=0;i<n;i++){ cout<<d[i]<<" "; } cout<<endl; system("pause"); return 0; } void dij(int s){ memset(d,INF,sizeof(d)); d[s] = 0; for(int i=0;i<n;i++){ int u=-1,MIN = INF; for(int j=0;j<n;j++){ if(vis[j]==false&&d[j]<MIN){ u = j; MIN = d[j]; } } if(u==-1){ return; } vis[u]=true; for(int j=0;j<(int)adj[u].size();j++){ int v = adj[u][j].v; if(vis[v]==false&&adj[u][j].vis+d[u]<d[v]){ d[v]=adj[u][j].vis+d[u]; } } } }
问题二:最短路
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的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
代码:
(1)邻接矩阵
#include<iostream> #include<algorithm> #include<queue> #include<cstdio> #include<cstdlib> #include<cstring> using namespace std; #define maxn 105 #define INF 0x3f3f3f3f void dij(int s); int G[maxn][maxn]; bool vis[maxn]; int d[maxn]; int n,m; int main(){ while(cin>>n>>m){ if(n==0&&m==0){ break; } memset(G,INF,sizeof(G)); for(int i=0;i<m;i++){ int x,y,z; cin>>x>>y>>z; G[x][y] = G[y][x] = z; } dij(1); cout<<d[n]<<endl; } return 0; } void dij(int s){ for(int i=1;i<=n;i++){ d[i]=G[1][i]; vis[i] = false; } d[s]=0; for(int i=1;i<=n;i++){ int u=-1,MIN = INF; for(int j=1;j<=n;j++){ if(vis[j]==false&&d[j]<MIN){ u = j; MIN = d[j]; } } if(u==-1){ return; } vis[u]=true; for(int v=1;v<=n;v++){ if(vis[v]==false&&G[u][v]!=INF&&G[u][v]+d[u]<d[v]){ d[v]= G[u][v]+d[u]; } } } }
(2)邻接表
#include<iostream> #include<algorithm> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> using namespace std; #define maxn 105 #define INF 0x3f3f3f3f struct node{ int v,vis; }; void dij(int s); vector<node> adj[maxn]; bool vis[maxn]; int d[maxn]; int n,m; int main(){ while(cin>>n>>m){ if(n==0&&m==0){ break; } for(int i=0;i<n;i++){ adj[i].clear(); } for(int i=0;i<m;i++){ int x,y,z; cin>>x>>y>>z; node temp; temp.vis = z; temp.v = y; adj[x].push_back(temp); temp.v = x; adj[y].push_back(temp); } dij(1); cout<<d[n]<<endl; } return 0; } void dij(int s){ memset(d,INF,sizeof(d)); for(int i=1;i<=n;i++){ vis[i]=false; } d[s]=0; for(int i=1;i<=n;i++){ int u=-1,MIN = INF; for(int j=1;j<=n;j++){ if(vis[j]==false&&d[j]<MIN){ u = j; MIN = d[j]; } } if(u==-1){ return; } vis[u]=true; for(int j=0;j<(int)adj[u].size();j++){ int v = adj[u][j].v; if(vis[v]==false&&adj[u][j].vis+d[u]<d[v]){ d[v] = adj[u][j].vis+d[u]; } } } }
二、Floyd算法
问题同最短路
代码:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int maxn = 105; #define INF 0x3f3f3f3f int a[maxn][maxn]; int n,m; void floyd(); int main(){ while(cin>>n>>m){ if(n==0&&m==0){ break; } memset(a,INF,sizeof(a)); while(m--){ int x,y,z; cin>>x>>y>>z; a[x][y]=a[y][x]=z; } floyd(); } return 0; } void floyd(){ int s=1; for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ if(a[i][k]!=INF){ for(int j=1;j<=n;j++){ if(a[i][j]>a[i][k]+a[k][j]){ a[i][j]=a[i][k]+a[k][j]; } } } } } printf("%d\n",a[s][n]); }