您的位置:首页 > 其它

单源最短路径问题(带权图)

2017-08-21 15:50 357 查看
一、问题

 带权有向图G(E,V), 找出从给定源顶点s到其它顶点v的权最小路径。

“最短路径” = 最小权

二、问题求解:

求1到5的最短路径值?



【代码实现】:

【我的代码】:    还挺好的吧。

写个代码模板,日后抄

#include <stack>
#include <vector>
#include <set>
#include <map>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
#define INF 0x3f3f3f3f
#define LEN 210
int vis[LEN]; ///标记浏览过的,
int dis[LEN]; ///源点到当前点的距离
int w[LEN][LEN],n;
void init1()
{
int i,j;
for(i=0;i<LEN;i++)
for(j=0;j<LEN;j++)
w[i][j]=INF;
}
void Dijkstra(int st)
{

memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) ///把当前位置的有连接的相邻点加进来
dis[i]=w[st][i];

dis[st]=0;
vis[st]=1; ///把起始点加进来

for(int i=1;i<=n;i++)
{

int x,m=INF; ///m为最小距离值
for(int y=1;y<=n;y++){
if(!vis[y]&&dis[y]<m){///取出不在mark里的最小的dis[i]
m=dis[y],x=y;
}
}
if(m==INF) break;
vis[x]=1; ///把x放进来
// for(int y=1;y<=n;y++){
// dis[y]=min(dis[y],dis[x]+w[x][y]);
// }
for(int j=1;j<=n;j++){ ///所谓的松弛操作
if(!vis[j]&&dis[j]>dis[x]+w[x][j]){
dis[j]=dis[x]+w[x][j];
}
}
cout<<dis[i]<<endl;
}
}

int main()
{
int i,j,line;
int a,b,d;
cin>>n>>line; ///输入点和边
init1();
for(i=0;i<line;i++)
{
cin>>a>>b>>d; ///输入各边的权值
if(w[a][b]>d){
w[a][b]=d;
}
}
Dijkstra(1); ///调用方法
///输出1到5的最短路径
cout<<dis[5]<<endl;
return 0;
}


【别人的代码】想看的就稍微看一下吧,学习她人精华,取其糟粕。

#include <iostream>

using namespace std;

#define MAX 9999999

#define LEN 210

int map[LEN][LEN];    //某点到某点两点间的的距离

int dist[LEN];              //记录当前点到源点的最短路径长度

int mark[LEN];           //加入进来的点的集合

//初始化map为正无穷大

void init(){

int i,j;

for(i=0;i<LEN;i++){

for(j=0;j<LEN;j++){

map[i][j]=MAX;

}

}

}

//n:多少条路  start:起始点

void myDijstra(int n,int start){

int i,j,min,k;

for(i=1;i<=n;i++){

mark[i]=0;//没有点加入

dist[i]=map[start][i];//初始

}

mark[start]=1;//把起始点加进来

dist[start]=0;

for(i=1;i<=n;i++){

min=MAX;

for(j=1;j<=n;j++){

if(!mark[j] && dist[j]<min){    //取出不在mark里的最小的dist[i]

min=dist[j];

k=j;//标记

}

}

if(min==MAX)

break;

mark[k]=1;//把K加进来

//做松弛操作

for(j=1;j<=n;j++){

if(!mark[j] && dist[j]>dist[k]+map[k][j]){

dist[j]=dist[k]+map[k][j];

}

}

}

}

int main(){

int i,j,n,line;

int a,b,d;

cin>>n>>line;   //输入点和边

init();

for(i=0;i<line;i++){

cin>>a>>b>>d;  //输入各边的权值

if(map[a][b]>d){

map[a][b]=map[b][a]=d;

}

}

myDijstra(n,1);//调用方法

//输出1到5的最短路径

cout<<dist[5]<<endl;

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: