• 算法长度K最短路问题(单源点最短路径+A*算法)Strut2教程java教程


    最近研究算法长度,稍微总结一下,以后继续补充:

        每日一道理
    “多难兴才”曾一度被人定为规律。请看:屈原被放逐而作《离骚》;司马迁受宫刑而作《史记》;欧阳修两岁丧父笃学而成才;曹雪芹举家食粥而写出了不朽的《红楼梦》;越王勾践卧薪尝胆而雪洗国耻;韩信遭胯下辱而统率百万雄兵……他们都是在与逆境搏斗中成为伟人的!
    /*
     *算法引入:
     *在单源点最短径路题问中,现实运用时还需晓得最短径路外,次短路或者第三短路;
     *即要晓得多条最短路,并出排其长度加增的序顺,即为K最短路题问;
     *
     *算法想思:
     *单源点最短径路+高等搜索A*;
     *A*算法结合了启发式方法和式形化方法;
     *启发式方法通过充分利用图给出的信息来动态地做出定决而使搜索数次大大下降;
     *式形化方法不利用图给出的信息,而仅通过数学的式形析分;
     *
     *算法通过一个估价数函f(h)来估计图中的以后点p到点终的距离,并由此定决它的搜索向方;
     *当这条径路失败时,它会实验其他径路;
     *对于A*,估价数函=以后值+以后置位到点终的距离,即f(p)=g(p)+h(p),每次扩展估价数函值最小的一个;
     *
     *对于K短路算法说来,g(p)为以后从s到p所走的径路的长度;h(p)为点p到t的最短路的长度;
     *f(p)的意思为从s按照以后径路走到p后再走到点终t一共少至要走多远;
     *
     *为了减速算计,h(p)需要在A*搜索之前停止预处理,只要将原图的有所边反向,再从点终t做一次单源点最短径路能就失掉每一个点的h(p)了;
     *
     *算法骤步:
     *(1),将有向图的有所边反向,以原点终t为源点,求解t到有所点的最短距离;
     *(2),新建一个优先列队,将源点s加入到列队中;
     *(3),从优先级列队中弹出f(p)最小的点p,如果点p就是t,则算计t出队的数次;
     *如果以后为t的第k次出队,则以后径路的长度就是s到t的第k短路的长度,算法结束;
     *否则遍历与p相连的有所的边,将扩展出的到p的邻接点信息加入到优先级列队;
     *
     *算法测试:
     *PKU2449(Remmarguts' Date)
     *
     *标题粗心:
     *求从s到t的第k短路的长度;
     */
    
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    #include<cstdio>
    #include<climits>
    #include<algorithm>
    using namespace std;
    
    const int INF=0xffffff;
    const int N=1010;
    const int M=100010;
    
    struct node1
    {
        int to;
        int w;
        int next;
    };
    
    node1 edge1[M],edge2[M];
    int head1[M],head2[M];
    int idx1,idx2;
    int dist[N];
    
    struct node2
    {
        int to;
        //g(p)为以后从s到p所走的径路的长度;h(p)为点p到t的最短路的长度;
        int g,f;//f=g+h,f(p)的意思为从s按照以后径路走到p后再走到点终t一共少至要走多远;
        bool operator<(const node2 &r ) const
        {
            if(r.f==f)
                return r.g<g;
            return r.f<f;
        }
    };
    
    void Addedge1(int u,int v,int w)
    {
        edge1[idx1].w=w;
        edge1[idx1].to=v;
        edge1[idx1].next=head1[u];
        head1[u]=idx1++;
    }
    
    void Addedge2(int u,int v,int w)
    {
        edge2[idx2].w=w;
        edge2[idx2].to=v;
        edge2[idx2].next=head2[u];
        head2[u]=idx2++;
    }
    
    bool SPFA(int s,int n,int head[],node1 edge[],int dist[])
    {
        queue<int>Q1;
        int inq[N];
        for(int i=0; i<=n; i++)
        {
            dist[i]=INF;
            inq[i]=0;
        }
        dist[s]=0;
        Q1.push(s);
        inq[s]++;
        while(!Q1.empty())
        {
            int q=Q1.front();
            Q1.pop();
            inq[q]--;
            if(inq[q]>n)//负权环
                return false;
            int k=head[q];
            while(k>=0)
            {
                if(dist[edge[k].to]>dist[q]+edge[k].w)
                {
                    dist[edge[k].to]=edge[k].w+dist[q];
                    if(!inq[edge[k].to])
                    {
                        inq[edge[k].to]++;
                        Q1.push(edge[k].to);
                    }
                }
                k=edge[k].next;
            }
        }
        return true;
    }
    
    int A_star(int s,int t,int n,int k,int head[],node1 edge[],int dist[])
    {
        node2 e,ne;
        int cnt=0;
        priority_queue<node2>Q;
        if(s==t)//当s==t时,距离为0的路不能算在这k短路中,所以需要求k+1短路;
            k++;
        if(dist[s]==INF)
            return -1;
        e.to=s;
        e.g=0;
        e.f=e.g+dist[e.to];
        Q.push(e);
    
        while(!Q.empty())
        {
            e=Q.top();
            Q.pop();
            if(e.to==t)//找到一条最短径路
            {
                cnt++;
            }
            if(cnt==k)//找到k短路
            {
                return e.g;
            }
            for(int i=head[e.to]; i!=-1; i=edge[i].next)
            {
                ne.to=edge[i].to;
                ne.g=e.g+edge[i].w;
                ne.f=ne.g+dist[ne.to];
                Q.push(ne);
            }
        }
        return -1;
    }
    
    int main()
    {
        int n,m;
        //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin);
        while(~scanf("%d%d",&n,&m))
        {
            memset(head1, -1, sizeof(head1));
            memset(head2, -1, sizeof(head2));
            idx1=idx2=0;
            int u,v,w;
            for(int i=0; i<m; i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                Addedge1(u,v,w);
                Addedge2(v,u,w);
            }
            int s,t,k;
            scanf("%d%d%d",&s,&t,&k);
            SPFA(t,n,head2,edge2,dist);//以原点终t为源点,求反向图中t到有所点的最短距离;
            int res=A_star(s,t,n,k,head1,edge1,dist);
            printf("%d\n",res);
        }
        return 0;
    }

    文章结束给大家分享下程序员的一些笑话语录: 不会,Intel会维持高利润,也会维持竞争局面,国外的竞争不是打死对方的那种。你看日本有尼康,佳能,索尼,都做相机,大家都过得很滋润。别看一堆厂,其实真正控制的是后面的那几个财团——有些竞争对手,后面其实是一家人。

  • 相关阅读:
    合并排序法-Java实现
    桶排序(heap sort)-Java实现
    Shell排序法-Java实现
    快速排序法-Java实现
    选择排序法-Java实现
    树状数组例题-数星星,简单题easy,校门外的树2,清点人数
    [USACO]骑马修栅栏 Riding the Fences
    tarjan 割点
    [USACO07OPEN]便宜的回文Cheapest Palindrome
    [AHOI2009]维护序列
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3053767.html
Copyright © 2020-2023  润新知