Dijkstra算法

Dijkstra算法

解决问题

  • 单源最短路径,图G=(V,E,W)

基本思想

  • 记源点为s,除s外任意顶点i到s的距离记为dis[i]
  • 维护一个集合S,集合S中的所有顶点到源点s的最短距离已经求出,初始S=
  • 每次向S集合中添加一个顶点pos,这个顶点pos是S集合外的,并且它是目前看来离源点s最近的(即当前dis[i]最小)
  • 对新加入的顶点pos,对其可到达点做松弛操作(更新到源点的距离)
  • 上述操作执行n-1次即可使得S=V

特性

  • 不能处理带负边的图,因为它每次都是处理能连到的边,对于不能直接相连但是有负边的情况它考虑不到

源码

#include<iostream>
#include<queue>
#include<list>
#include<vector>
#include<cstring>
#include<set>
#include<stack>
#include<map>
#include<cmath>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;
typedef long long ll;
#define MS(x,i) memset(x,i,sizeof(x))
#define rep(i,s,e) for(int i=s; i<=e; i++)
#define sc(a) scanf("%d",&a)
#define scl(a) scanf("%lld",&a)
#define sc2(a,b) scanf("%d %d", &a, &b)
#define debug printf("debug......\n");
#define pfd(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
const double eps=1e-8;
const double PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x7fffffff;
const int maxn = 1e3+10;
int dx[4] = {0, 0, 1, -1};
int dy[4]  = {1, -1, 0 , 0};

int dis[maxn];
int G[maxn][maxn];
int n,m;//n个结点 m条边
bool vis[maxn];
void dijkstra(int s){
    MS(vis , 0);
    rep(i,1,n){
        dis[i] = G[s][i];
    }
    vis[s] = 1;//s加入S集合

    //只需要再将n-1个点加入S集合
    rep(i, 1 , n-1){
        int minx = inf;//对于每一次找点,都要找当前最短路的点
        int pos;//记录一下是哪个点
        rep(j , 1 , n){
            if(!vis[j] && dis[j] < minx){
                minx = dis[j];
                pos = j;
            }
        }
        //pos顶点加入S集合
        vis[pos] = 1;
        //由于pos顶点的进入 对S集合以外的结点 其距离因为pos的加入需要进行更新
        rep(k, 1 , n){
            if(!vis[k] && dis[k] > dis[pos] + G[pos][k]){
                dis[k] = dis[pos] + G[pos][k];
            }
        }
    }
}


int main(){
    int x,y,w;
    ios::sync_with_stdio(false);
    while(cin>>n>>m){
        if(n==0 && m==0) break;
        //初始化
        rep(i,1,n)
        rep(j,1,n){
            if(i == j) G[i][j] = 0;
            else G[i][j] = inf;
        }
        rep(i,1,m){
            cin>>x>>y>>w;
            G[x][y] = w;
            G[y][x] = w;
        }
        dijkstra(1);
        //rep(i,1,n) cout<<dis[i]<<" ";
        int e;
        while(cin>>e)
            cout<<dis[e]<<endl;
    }
    return 0;
}

posted @ 2019-04-16 10:30  西风show码  阅读(134)  评论(0编辑  收藏  举报