zoukankan      html  css  js  c++  java
  • poj2449 Remmarguts' Date

    题目大意:

    给出一个图,然后给出一个起点个一个终点,求这两点间的第K短路。

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

    /*
        边可以重复走,
        不严格的k短路
        A*
        估价函数为dis(起点,i)+dis(i,终点)
        
        1、反向图上求出终点到每个点的最短路
        2、起点入优先队列,
          队首出队,
          如果队首是终点,而且是第k次出队,
           那么当前距离就是k短路
          如果队首不是终点,便利与当前点连接的所有的点,入队
        
        细节1:优先队列出入队不用vis数组判重,因为边可以重复走
        细节2:如果第1步中,起点与终点不连通,输出-1结束,
            否则进入A*,没有vis数组,出现环会死循环
        细节3:如果起点=终点,令k++,因为起点会立即出队
    */
    #include<iostream> 
    #include<cstdio>
    #include<queue>
    #define inf 999999999
    using namespace std;
    int n,m,s,t,k,num1,head1[1010],num2,head2[1010],dis[1010];
    bool vis[1010];
    struct node{
        int to,pre,v;
    }e1[100010],e2[100010];
    void Insert1(int from,int to,int v){
        e1[++num1].to=to;
        e1[num1].v=v;
        e1[num1].pre=head1[from];
        head1[from]=num1;
    }
    void Insert2(int to,int from,int v){
        e2[++num2].to=to;
        e2[num2].v=v;
        e2[num2].pre=head2[from];
        head2[from]=num2;
    }
    void spfa(){
        for(int i=1;i<=n;i++)dis[i]=inf;
        queue<int>q;
        q.push(t);dis[t]=0;vis[t]=1;
        while(!q.empty()){
            int now=q.front();q.pop();vis[now]=0;
            for(int i=head2[now];i;i=e2[i].pre){
                int to=e2[i].to;
                if(dis[to]>dis[now]+e2[i].v){
                    dis[to]=dis[now]+e2[i].v;
                    if(!vis[to]){
                        q.push(to);
                        vis[to]=1;
                    }
                }
            }
        }
    }
    struct Node{
        int d,id;
        bool operator < (Node x)const{
            return d+dis[id]>x.d+dis[x.id];
        }
    }nxt;
    void Astar(){
        if(dis[s]==inf){
            printf("-1");
            return;
        }
        if(s==t)k++;
        priority_queue<Node>q;
        int cnt=0;
        Node now;
        now.id=s;
        now.d=0;
        q.push(now);
        while(!q.empty()){
            now=q.top();q.pop();
            if(now.id==t){
                cnt++;
                if(cnt==k){
                    printf("%d",now.d);
                    return;
                }
            }
            for(int i=head1[now.id];i;i=e1[i].pre){
                int to=e1[i].to;
                nxt.id=to;
                nxt.d=now.d+e1[i].v;
                q.push(nxt);
            }
        }
        printf("-1");
    }
    int main(){
        scanf("%d%d",&n,&m);
        int x,y,z;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            Insert1(x,y,z);
            Insert2(x,y,z);
        }
        scanf("%d%d%d",&s,&t,&k);
        spfa();
        Astar();
        return 0;
    }
  • 相关阅读:
    Android 测试工具集01
    Android ImageView的ScaleType属性
    Android Webview与Html5交互
    Java Notes 00
    Android 显示原理简介
    Android开发在路上:少去踩坑,多走捷径
    Android_Dialog cancle 和dismiss 区别
    SpringMVC框架
    Redis持久化
    Redis集群
  • 原文地址:https://www.cnblogs.com/thmyl/p/7470331.html
Copyright © 2011-2022 走看看