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

来源:互联网 发布:java nanotime 唯一 编辑:程序博客网 时间:2024/06/05 12:08

一、问题

 带权有向图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 210int 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;    } 


原创粉丝点击