zoukankan      html  css  js  c++  java
  • Dijkstra算法

    Dijkstra算法

    解决问题

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

    基本思想

    • 记源点为s,除s外任意顶点i到s的距离记为dis[i]
    • 维护一个集合S,集合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......
    ");
    #define pfd(x) printf("%d
    ",x)
    #define pfl(x) printf("%lld
    ",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;
    }
    
    
  • 相关阅读:
    Linux shell中运行命令后加上字符“&”的作用(转)
    初探Nginx架构
    NeoLoad系列- 快速上手教程
    Web服务器性能压力测试工具
    Web页面性能测试工具浅析
    主流压力测试工具推荐
    Jmeter系列-webdriver代码范例
    Jmeter系列-webdriver插件
    Jmeter系列-自动生成html报告
    loadrunner如何监控windows系统的资源
  • 原文地址:https://www.cnblogs.com/czsharecode/p/10715388.html
Copyright © 2011-2022 走看看