图的最短路径求法有两种,
- Dijkstra求单源最短路,
- floyd算法求任意两点的最短路。
Dijkstra算法
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1000+10;
const int inf=0x3f3f3f3f;
int dist[maxn][maxn];
int d[maxn];
int vis[maxn];
int n,m,st,en;
int path[maxn];
void white(int x)
{
if(path[x]==0)
{
cout<<"v"<<st<<" ";
return ;
}
white(path[x]);
cout<<"v"<<path[x]<<" ";
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
scanf("%d%d",&st,&en);
memset(dist,inf,sizeof(dist));
memset(vis,0,sizeof(vis));
memset(path,0,sizeof(path));
for(int i=1; i<=m; i++)
{
int u,v,d;
scanf("%d%d%d",&u,&v,&d);
dist[u][v]=d;
}
memset(vis,0,sizeof(vis));
for(int i=0; i<n; i++)
if(i==st)
d[i]=0;
else
d[i]=inf;
for(int i=1; i<=n; i++)
{
int x,min_dist=inf;
for(int y=0; y<n; y++)
if(!vis[y]&&min_dist>=d[y])
min_dist=d[x=y];
vis[x]=true;
if(x==en)
break;
for(int y=0; y<n; y++)
if(d[y]>d[x]+dist[x][y])
{
path[y]=x;
d[y]=d[x]+dist[x][y];
}
}
if(d[en]!=0&&d[en]<inf)
{
cout<<d[en]<<endl;
white(en);
cout<<"v"<<en;
}
else
{
cout<<"no answer";
}
}
}
floyd算法
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1000+10;
const int inf=0x3f3f3f3f;
int dist[maxn][maxn];
int path[maxn][maxn];
int n,m;
void white(int i,int j)
{
if(path[i][j]==-1) return ;
int k=path[i][j];
white(i,k);
cout<<'v'<<k<<" ";
white(k,j);
}
int main()
{
scanf("%d%d",&n,&m);
memset(path,-1,sizeof(path));
memset(dist,inf,sizeof(dist));
for(int i=1;i<=m; i++)
{
int u,v,d;
scanf("%d%d%d",&u,&v,&d);
dist[u][v]=d;
}
for(int k=0; k<n; k++)
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
{
if(k==i||i==j)
continue;
if(dist[i][j]>dist[i][k]+dist[k][j])
{
dist[i][j]=dist[i][k]+dist[k][j];
path[i][j]=k;
}
}
bool flag=false;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
{
if(dist[i][j]!=inf)
{
flag=true;
cout<<dist[i][j]<<" ";
cout<<'v'<<i<<" ";
white(i,j);
cout<<'v'<<j<<endl;
}
}
if(!flag)
cout<<"no answer"<<endl;
return 0;
}