• 最短路径


    1.单元单点最短路径问题

    最简单的遍历从源节点S开始,相邻结点有很多,

    1.1 深度优先与广度优先

    深度优先搜索是一直往前走,只要前面有路,走到没有路为止

    广度优先一源点为圆心画一个越来愈大的圆

    dijkstra算法:不能处理负权值(效率不错)

    //复习dijstra算法  不能判断负权值 
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int M=0x7fffffff;
    int a[1500][1500]; //存两点之间的距离
    int dis[1500];//存点到目标点的距离
    int book[1500];//标记已经访问的点
    int m,n; //m表示点个数 
    void dijstra(int m){
        int flag,u; 
        memset(book,0,sizeof(book));
    //    for(int i=1;i<m;i++) cout<<book[i]<<endl;
    //    cout<<"hello"<<endl;//2
        for(int i=0;i<m;i++) 
        dis[i]=a[0][i];
        book[0]=1;
        for(int i=0;i<m-1;i++){ //表示有n-1次比较 
            flag=M;
        for(int j=1;j<m;j++){//寻找没访问的剩下的离0最近的点 
            if(book[j]==0&&dis[j]<flag){
                flag=dis[j];
                u=j;
            } 
        }
        book[u]=1;
        //松弛判断 全局判断 
        for(int x=1;x<m;x++) {
            if(a[u][x]<M){
                if(dis[x]>dis[u]+dis[u]+a[u][x]) dis[x]=dis[u]+a[u][x];  //由u作为切换点 
            }
        }     
        }
    //    cout<<"接过"<<endl;
        for(int i=1;i<m;i++) cout<<dis[i]<<endl;
    }  
    int main()
    {
    //    int m,n,u,v,l;    错误出现在这里
    int u,v,l; 
        cin>>m>>n;
        memset(a,0x7f,sizeof(a));
        for(int i=0;i<n;i++){
            cin>>u>>v>>l;
            a[u-1][v-1]=l;
            a[i][i]=0;
        }
        dijstra(m);
    } 
    View Code

    SPFA算法:可以处理负权值(必须掌握)

    //SPFA算法  可以处理负权值 处理正权值比不上dijstra 
    #include <iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define MAX 200001
    #define INF 99999999
    typedef struct XNode  //链表做好 
    {
        int pow;//边的权值
        int adjvex;//
        struct XNode *next;
    }Node; 
    
    Node * head[MAX];
    int visit[MAX],dis[MAX];//标记与距离 
    void add(int u,int v,int w)
    {
        Node *p;
        p=(Node*)malloc(sizeof(Node)); //创建新的结点 
        p->pow=w; //权值 
        p->adjvex=v;//
        p->next=head[u]; //下一个点 
        head[u]=p; //出发点 
    }
    void SPFA(int n)
    {
        int u,v,w;
        queue<int>Q;//这个算法关键使用队列来处理问题
        Node *p;
        for(int i=1;i<=n;i++)//初始化
        {
            visit[i]=0; //未被访问 
            dis[i]=INF;//距离初始最远 
        }
        Q.push(1);//头结点进队
        dis[1]=0;
        visit[1]=1;
        while(!Q.empty())//直到队列为空才结束循环
        {
            u=Q.front();//头结点
            Q.pop();//进队
            for(p=head[u];p!=NULL;p=p->next)
            {
                v=p->adjvex;
                w=p->pow;
                if(dis[u]+w<dis[v])
                {
                    dis[v]=dis[u]+w;
                    if(!visit[v])
                    {
                        visit[v]=1;
                        Q.push(v);//出队
                    }
                }
            }
        }
    }
    int main()
    {
        int n,m,u,v,w;
        while(cin>>n>>m){
        memset(head,NULL,sizeof(head));//初始化链表 
        for(int i=1;i<=m;i++)
        {
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
        }
        SPFA(n);
        for(int i=2;i<=n;i++)
            cout<<dis[i]<<endl;
        }
        return 0;
    }
    View Code

     bell_man算法:理解就行

     2.多点最短路径问题

  • 相关阅读:
    mysql
    mysql
    mysql
    mysql
    sed编辑命令
    awk正则应用
    awk运算符
    awk命令细节
    uniq命令
    sort命令
  • 原文地址:https://www.cnblogs.com/helloworld2019/p/10370135.html
Copyright © 2020-2023  润新知