• 第k短路


    题:http://poj.org/problem?id=2449

    题意:

      题目大意就是给出一个图,然后给出一个起点个一个终点,求这两点间的第K短路。

      本题中是可以走重复的路的,所以如果一张图中有一个环的话,无论求第几短路都是存在的。

    分析:

      A*===优化的bfs

      这里预估函数用的是该点到t的最短路值。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int M=1e5+5;
    const int inf=0x3f3f3f3f;
    int tot,head[M],rhead[M],dis[M],cnt[M],vis[M];
    struct E{
        int v,w,nextt;
    }e[M],re[M];
    void addedge(int u,int v,int w){
        e[tot].v=v;
        e[tot].w=w;
        e[tot].nextt=head[u];
        head[u]=tot;
        re[tot].v=u;
        re[tot].w=w;
        re[tot].nextt=rhead[v];
        rhead[v]=tot++;
    }
    void spfa(int s,int n){
        for(int i=0;i<=n;i++)
            cnt[i]=0,dis[i]=inf,vis[i]=0;
        queue<int>que;
        que.push(s);
        dis[s]=0;
        cnt[s]=1;
        while(!que.empty()){
            int  u=que.front();
            que.pop();
            vis[u]=0;
            for(int i=rhead[u];~i;i=re[i].nextt){
                int v=re[i].v;
                if(dis[v]>dis[u]+re[i].w){
                    dis[v]=dis[u]+re[i].w;
                    if(!vis[v]){
                        que.push(v);
                        vis[v]=1;
                        if(++cnt[v]>n)
                            return ;
                    }
                }
            }
        }
        return ;
    }
    struct node{
        /*friend bool operator<(node n1,node n2){
            return n1.dist>n2.dist;
        }*/
        int x,dist;
        bool operator < (const node &b)const{
            return this->dist>b.dist;
        }
    };
    priority_queue<node>q;
    int main(){
        int n,m;
        while(~scanf("%d%d",&n,&m)){
            tot=0;
            for(int i=0;i<=n;i++)
                head[i]=-1,rhead[i]=-1;
            while(m--){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
            }
            int s,t,k;
            scanf("%d%d%d",&s,&t,&k);
            spfa(t,n);
            if(dis[s]==inf){
                puts("-1");
                continue;
            }
            while(!q.empty())
                q.pop();
            node sta;
            sta.x=s,sta.dist=dis[s];
            q.push(sta);
            int ans=-1,num=0;
            if(s==t)
                k++;
            while(!q.empty()){
                node temp=q.top();
                q.pop();
                int u=temp.x;
                if(u==t){
                    num++;
                    if(num==k){
                        ans=temp.dist;
                        break;
                    }
                }
                for(int i=head[u];~i;i=e[i].nextt){
                    int v=e[i].v;
                    node close;
                    close.x=v;
                    close.dist=temp.dist-dis[u]+dis[v]+e[i].w;
                    q.push(close);
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    理解C#系列 / 核心C# / 常量
    理解C#系列 / 核心C# / 变量
    理解C#系列 / C#语言的特性
    理解C#系列 / .NET体系结构
    利用DMZ对象保护全局变量
    随手翻的一道摩拜校招题
    关于为函数形参赋值和搜索变量标识符的云云
    竟然修改形参有这么可怕的后果!!
    牛得一逼的delete操作符
    屏蔽属性
  • 原文地址:https://www.cnblogs.com/starve/p/12109748.html
Copyright © 2020-2023  润新知