最短路径
· 对于图G<V,E>,在非网图中最短路径是,两顶点之间的经过边的条数最小,而在网图中,最短路径是两顶点之间经过的边的权值之和最小。
注:路径起点称为源点,最后一个顶点称为终点。
图的最短路径求法,有两种,Dijkstra求单源最短路,floyd算法求任意两点的最短路。
Dijkstra算法
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
using namespace std;
int m[101][101],dist[101],ans[101],n,e,begin1,end1,maxx;
string v[101];
string path[101][101];
void pre(){
for(int i=0;i<n;i++){
stringstream a;
a<<i;
a>>v[i];
v[i]="v"+v[i];
}
}
void solve(){
for(int i=0;i<n;i++){
dist[i]=m[begin1][i];
path[begin1][i]=v[begin1]+" "+v[i];
}
dist[begin1]=0;
for(int s=1;s<n;s++){
int min1=1061109567,tmp=0;
for(int i=0;i<n;i++){
if(dist[i]!=0&&dist[i]<=min1){
min1=dist[i];
tmp=i;
}
}
for(int i=0;i<n;i++){
if(dist[i]>dist[tmp]+m[tmp][i]){
path[begin1][i]=path[begin1][tmp]+" "+v[i];
dist[i]=dist[tmp]+m[tmp][i];
}
}
ans[tmp]=dist[tmp];
dist[tmp]=0;
}
if(ans[end1]==1061109567) cout<<"no answer"<<endl;
else cout<<ans[end1]<<endl<<path[begin1][end1]<<endl;
}
int main()
{
int f,s,w;
cin>>n>>e;
cin>>begin1>>end1;
memset(m,0x3f,sizeof(m));
pre();
for(int i=0;i<n;i++) m[i][i]=0;
for(int i=1;i<=e;i++){
cin>>f>>s>>w;
m[f][s]=w;
maxx=max(maxx,w);
}
solve();
}
Floyd算法
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#define INF 1061109567
using namespace std;
int n,m;
string path[101][101],v[101];
int a[101][101];
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++){
stringstream ss;
ss << i;
ss >> v[i];
v[i]="v"+v[i];
//cout<<v[i]<<endl;
}
memset(a,0x3f,sizeof(a));
for(int i=0;i<n;i++){
}
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
cin>>a[x][y];
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a[i][j]!=INF){
path[i][j]=v[i]+" "+v[j];
}
else path[i][j]="";
}
}
for(int k=0;k<n;k++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a[i][j]>a[i][k]+a[k][j]){
a[i][j]=a[i][k]+a[k][j];
path[i][j]=path[i][k]+" "+v[j];
}
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a[i][j]!=INF&&i!=j){
cout<<a[i][j]<<" ";
cout<<path[i][j]<<endl;
}
}
}
}