最短路径
单源最短路径
Dijkstra算法
不能存在负权边
#include <bits/stdc++.h>
using namespace std;
int p[100];//前驱
void print(int y)
{
if(p[y]!=0)print(p[y]);
cout<<y<<' ';
}
int main()
{
int a[100][100];//邻接矩阵
int d[100];
bool u[100];
int max1=2<<20;
cin>>n>>e;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=max1;
for(int i=1;i<=e;i++)
{
int x,y,w;
cin>>x>>y>>w;
a[x][y]=w;a[y][x]=w;//无向图
}
int x,y;
cin>>x>>y;//x为源点,y为终点
memset(u,0,sizeof(u));
u[x]=1;d[x]=0;
for(int i=1;i<=n;i++)
d[i]=a[x][i],p[i]=x;
p[x]=0;
for(int i=1;!u[y]&&i<=n-2;i++)
{
int m=max1,k;
for(int j=1;j<=n;j++)
if(d[j]<m&&!u[j])
{
m=d[j];
k=j;
}
if(m==max1) break;
u[k]=1;
for(j=1;j<=n;j++)
if(d[k]+a[k][j]<d[j])
{
d[j]=d[k]+a[k][j];
p[j]=k;
}
}
cout<<d[y]<<endl;
print(y);
return 0;
}
SPFA算法
可含负权边,可用于判断图中是否含负环。
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int>q;
int a[100][100],d[100],t[100];
bool u[100];
int max1=2<<20,n,e;
cin>>n>>e;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=max1;
for(int i=1;i<=e;i++)
{
int x,y,w;
cin>>x>>y>>w;
a[x][y]=w;//有向图
}
int x;
cin>>x;
for(int i=1;i<=n;i++)
d[i]=max1;
d[x]=0;
memset(u,0,sizeof(u));
memset(t,0,sizeof(t));
q.push_back(x);
u[x]=1;t[x]=1;
while(!q.empty())
{
int k=q[0];
for(int i=1;i<=n;i++)
if(d[k]+a[k][i]<d[i])
{
d[i]=d[k]+d[k][i];
if(!u[i])
{
q.push_back(i);
t[i]++;
if(t[i]==n)
{
cout<<"有负环!";
return 0;
}
}
u[i]=1;
}
u[k]=0;
q.erase(q.begin());
}
for(int i=1;i<=n;i++)
cout<<d[i]<<' ';
return 0;
}
任意一对顶点之间的最短路径
Floyd算法
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a[100][100];
int max1=2<<20,n,e;
cin>>n>>e;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
a[i][j]=max1;
a[i][i]=0;
}
int x,y,w;
for(int i=1;i<=e;i++)
{
cin>>x>>y>>w;
a[x][y]=w;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
return 0;
}