5778: 城市路 dijkstra/spfa(邻接矩阵/邻接表)
描述
罗老师被邀请参加一个舞会,是在城市n,而罗老师当前所处的城市为1,附近还有很多城市2~n-1,有些城市之间没有直接相连的路,有些城市之间有直接相连的路,这些路都是双向的,当然也可能有多条。
现在给出直接相邻城市的路长度,罗老师想知道从城市1到城市n,最短多少距离。
输入
输入n, m,表示n个城市和m条路;
接下来m行,每行a b c, 表示城市a与城市b有长度为c的路。
输出
输出1到n的最短路。如果1到达不了n,就输出-1。
样例输入
5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100
样例输出
90
提示
【数据规模和约定】
1≤n≤2000
1≤m≤10000
0≤c≤10000
dijkstra:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 2005,inf = 1e9; 4 int vis[N],dis[N],g[N][N]; 5 int n,m,w; 6 void dijstra() 7 { 8 for(int i=1;i<=n;i++)dis[i] = g[1][i]; 9 dis[1] = 0; 10 vis[1] = 1; 11 int pos,minn; 12 for(int i=1;i<=n;i++) 13 { 14 minn = inf; 15 for(int j=1;j<=n;j++) 16 { 17 if(!vis[j] && minn>dis[j]) 18 { 19 pos = j;//找到从1出发可以到达的最短的点j 20 minn = dis[j]; 21 } 22 } 23 vis[pos] = 1; //出发去j,标记上 24 for(int j=1;j<=n;j++) 25 { 26 if(dis[j]>dis[pos]+g[pos][j]) //如果1到j的距离比到达最短的点pos的距离+pos到j的距离远,那就更新替换 27 { 28 dis[j] = dis[pos]+g[pos][j]; 29 } 30 } 31 } 32 } 33 int main() 34 { 35 cin>>n>>m; 36 memset(g,127,sizeof(g)); 37 for(int i=1;i<=m;i++) 38 { 39 int x,y,z; 40 cin>>x>>y>>z; 41 if(z<g[x][y])g[x][y] = g[y][x] = z; 42 } 43 dijstra(); 44 if(dis[n]<inf)cout<<dis[n]; 45 else cout<<-1; 46 return 0; 47 }
spfa:邻接矩阵存储
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int inf = 0x3f3f3f3f; 4 int g[2005][2005],vis[2005],dis[2005]; 5 int n,m; 6 void spfa(int s) 7 { 8 memset(dis,inf,sizeof(dis)); 9 dis[1] = 0;vis[1] = 1; 10 queue<int>q; 11 q.push(1); 12 while(!q.empty()) 13 { 14 int f = q.front();q.pop(); 15 vis[f] = 0; 16 for(int i=1;i<=n;i++) 17 { 18 int d = g[f][i]; 19 if(d==inf)continue; 20 if(dis[i]>dis[f]+d) 21 { 22 dis[i] = dis[f]+d; 23 if(vis[i]==0) 24 { 25 q.push(i); 26 vis[i] = 1; 27 } 28 } 29 } 30 } 31 } 32 int main() 33 { 34 //freopen("help.in","r",stdin); 35 //freopen("help.out","w",stdout); 36 cin>>n>>m; 37 memset(g,inf,sizeof(g)); 38 for(int i=1;i<=n;i++)g[i][i] = 0; 39 for(int i=1;i<=m;i++) 40 { 41 int x,y,z; cin>>x>>y>>z; 42 if(z<g[x][y])g[x][y] = g[y][x] = z; 43 } 44 spfa(1); 45 if(dis[n]==inf)cout<<"-1"; 46 else cout<<dis[n]; 47 return 0; 48 }
spfa:邻接表vector存储
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int inf = 0x3f3f3f3f; 4 int vis[2005],dis[2005]; 5 int n,m; 6 struct node{ 7 int d,to; //g[i].to是代表i和to链接 ,g[i].d代表从i到to的距离是d 8 }; 9 vector<node> g[2005]; 10 void spfa(int s) 11 { 12 memset(dis,inf,sizeof(dis)); 13 dis[1] = 0;vis[1] = 1; 14 queue<int>q; 15 q.push(1); 16 while(!q.empty()) 17 { 18 int f = q.front();q.pop(); 19 vis[f] = 0; 20 for(int i=0;i<g[f].size();i++) 21 { 22 node t = g[f][i]; 23 if(dis[t.to]>dis[f]+t.d) 24 { 25 dis[t.to] = dis[f]+t.d; 26 if(vis[t.to]==0) 27 { 28 q.push(t.to); 29 vis[t.to] = 1; 30 } 31 } 32 } 33 } 34 } 35 int main() 36 { 37 //freopen("help.in","r",stdin); 38 //freopen("help.out","w",stdout); 39 cin>>n>>m; 40 for(int i=1;i<=m;i++) 41 { 42 int x,y,z; cin>>x>>y>>z; 43 node t1,t2; 44 t1.d = t2.d = z; 45 t1.to = y; t2.to = x; 46 g[x].push_back(t1); 47 g[y].push_back(t2); 48 49 } 50 spfa(1); 51 if(dis[n]==inf)cout<<"-1"; 52 else cout<<dis[n]; 53 return 0; 54 }