图的最短路径问题是永恒的问题!
常考。(就算期末考试不考)
最短路径的算法……数也数不过来,不过我还没听说过有环的可以求最短路径的~可能是孤陋寡闻了。
数据结构课上只学习了最简单的Floyd算法和Dijkstra算法。
但是Dijkstra算法我还是不熟悉!
嘤嘤嘤。
Floyd算法
Floyd虽然逻辑上很难思考,但是代码异常的好写~
求得是所有的点到其他的所有点的最短路径,
但是我打的代码仿佛有个不知名的bug嘤嘤嘤,不知道为什么会有的点会经过好几次。
思想:对每两个点的路径进行vNum次比较,每次都保存下来最短的路径已经经过的点,最终得到所有的点到其他的点的最短路径。
代码:
#include<iostream>
#include<cstring>
using namespace std;
int a[100][100];
string s[100][100];
string v[100];
int n,m;
int main()
{
cin>>n>>m;
int b,e,p;
memset(a,0x3f,sizeof(a));
for(int i=0;i<n;i++)
{
v[i]='0'+i;
}
for(int i=1;i<=m;i++)
{
cin>>b>>e>>p;
a[b][e]=p;
s[b][e]=v[b]+v[e];
}
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];
s[i][j]=s[i][k]+s[k][j];
}
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i!=j)
{
if(a[i][j]!=0x3f)
{
cout<<a[i][j];
for(int k=0;k<s[i][j].size();k++)
{
if(s[i][j][k]!=s[i][j][k-1])
cout<<" v"<<s[i][j][k];
}
cout<<endl;
}
else{
cout<<"no answer"<<endl;
}
}
}
}
}
Dijkstra算法
它主要是求出单个节点到其他的所有点的最短路径。
思想:
1.设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,
2.对vi∈V-S,假设从源点v到vi的有向边为最短路径(从v到其余顶点的最短路径的初值)。
3.以后每求得一条最短路径v, …, vk,就将vk加入集合S中,并将路径v, …, vk , vi与原来的假设相比较,取路径长度较小者为最短路径。
重复上述过程,直到集合V中全部顶点加入到集合S中。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[101][101];
string s[101];
string v[101];
int dis[101];
int n,m;
int bb,ee;
string ss;
int vis[100];
int Min(int v[],int n)
{
int min=1000;
int k=-1;
for(int i=0;i<n;i++)
{
if(min>v[i]&&vis[i]!=1)
{
min=v[i];
k=i;
}
}
return k;
}
void dijkstra(int o)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
dis[i]=a[o][i];
if(dis[i]<100)
{
s[i]=v[o]+v[i];
}
else s[i]="";
}
vis[o]=1;
for(int num=0;num<n;num++)
{
int k=Min(dis,n);
if(k==-1) return;
for(int i=1;i<n;i++)
if(dis[i]>dis[k]+a[k][i]&&vis[k]!=1){
dis[i]=dis[k]+a[k][i];
s[i]=s[k]+v[i];
}
vis[k]=1;
}
}
int main()
{
cin>>n>>m;
cin>>bb>>ee;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
a[i][j]=100;
s[i]="";
}
for(int i=0;i<n;i++)
{
v[i]='0'+i;
}
int b,e,p;
for(int i=1;i<=m;i++)
{
cin>>b>>e>>p;
a[b][e]=p;
}
dijkstra(bb);
if(dis[ee]<100)
{
cout<<dis[ee]<<endl;
for(int i=0;i<s[ee].size();i++)
{
cout<<"v"<<s[ee][i];
if(i!=s[ee].size()-1) cout<<" ";
}
cout<<endl;
}
else cout<<"no answer"<<endl;
}