zoukankan      html  css  js  c++  java
  • 第K短路模板【POJ2449 / 洛谷2483 / BZOJ1975 / HDU6181】

    1.到底如何求k短路的?

          我们考虑,要求k短路,要先求出最短路/次短路/第三短路……/第(k-1)短路,然后访问到第k短路。

          接下来的方法就是如此操作的。

    2.f(x)的意义?

          我们得到的f(x)更小,优先访问这个f(x)的点。

          我们可以定义一组数{p,g,h},p是某一个点,g是估价,h是实际,那么g+h更小的点p会优先访问。

          为什么呢?因为假设我们求出了w短路,接下来要求(w+1)短路,就要求最小的另一条路径。

          应该易理解。

    3.为什么选择最短路来估价?

          很简单的选择,我们既然要求最短了,当然是找最短路。

          事实上这不是我们的初衷,但是有了“先求(k-1)短路”的概念后,这么理解也可以了。

    4.实现

          实现是比较简单的。

          如何预处理出g(x)呢?显然,将所有边反向,然后求end到所有点的单源最短路径就好了。

          接下来的启发式搜索可以简单解决。

    事实上,就是在暴力搜索的基础上增加了启发式搜索:往一个最优的点的地方走。

    另外还是要专来一篇这题blog的QAQ

    关于上题目的程序:

    86ms

    #include<iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int N=100000+10;
    const int inf=0x3f3f3f3f;
    struct edge
    {
        int u,v,w,next;
    }e[N<<1];
    int head[N<<1],head1[N<<1],dis[N<<1],vis[N<<1],cnt[N<<1];
    int num;
    int n,m;
    int s,t,k;
    struct node
    {
        int g,h;
        int to;
        bool operator<(node a)const
        {
            return a.h+a.g<h+g;
        }
    };
    void init()
    {
        num=0;
        memset(head1,-1,sizeof(head1));
        memset(head,-1,sizeof(head));
    }
    void addegde(int u,int v,int w)
    {
        e[num].v=v;
        e[num].w=w;
        e[num].next=head[u];
        head[u]=num++;
        e[num].v=u;
        e[num].w=w;
        e[num].next=head1[v];
        head1[v]=num++;
    }
    void spfa()
    {
        memset(vis,0,sizeof(vis));
        memset(dis,inf,sizeof(dis));
        dis[t]=0;
        vis[t]=1;
        queue<int>q;
        q.push(t);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head1[u];i!=-1;i=e[i].next)
            {
                int v=e[i].v;
                if(dis[v]>dis[u]+e[i].w)
                {
                    dis[v]=dis[u]+e[i].w;
                    if(!vis[v])
                    {
                        q.push(v);
                        vis[v]=1;
                    }
                }
            }
        }
    }
    int AA()
    {
        memset(cnt,0,sizeof(cnt));
        priority_queue<node>Q;
        node p,q;
        p.g=0;
        p.to=s;
        p.h=dis[s];
        Q.push(p);
        while(!Q.empty())
        {
            q=Q.top();
            Q.pop();
            cnt[q.to]++;
            if(cnt[q.to]>k)
                continue;
            if(cnt[t]==k)
                return q.g;
            for(int i=head[q.to];i!=-1;i=e[i].next)
            {
                int v=e[i].v;
                p.to=v;
                p.g=q.g+e[i].w;
                p.h=dis[v];
                Q.push(p);
            }
        }
        return -1;
    }
    int main()
    {
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            scanf("%d%d",&s,&t);
            init();
            for(int i=0;i<m;i++)
            {
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                addegde(u,v,w);
            }
            
            spfa();
            if(s==t)k++;
            //cout<<dis[s]<<endl;
            int ans=AA();
            printf("%d
    ",ans);
        }
        return 0;
    }
    SPFA+A*
  • 相关阅读:
    Linux系统负载
    full nat
    close wait 状态的随想
    记录一下 性能分析问题
    golang 反射
    socket里面那个又爱又恨的锁
    Difference between skbuff frags and frag_list
    浅析TCP协议---转载
    http 怎样关闭
    http 响应 ngx_http_send_header ngx_http_output_filter
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9441194.html
Copyright © 2011-2022 走看看