• poj2449 (第k条最短路)


    题意:求n个点中,a到b的第k条最短路

    思路:

    用最短路求出估价函数的h,再在搜索过程中记录g,利用A*求出

    最开始想到的便是A*和最短路,但是脑子抽了,居然一个一个去求- -,TL了后才发现可以倒着求最短路一次搞定。

    但是又发现没考虑重边的问题,又换了种姿势终于AC,感觉太习惯于直接开二维数组,这不行啊- -

    当from = to时,因为还没出发就已经判定k--,所以在其相等时,k+=1


    问题:

    1.对算法的理解不够透彻- -

    2.在题目上考虑不够全面,导致不得不重写代码

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <functional>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    typedef long long ll;
    int vis[1005];
    int low[1005];
    int head[1005],head1[1005];
    int from,to;
    int tot;
    int n,m,k;
    struct edge
    {
        int u,v;
        int len;
        int next;       //正向
        int next1;      //反向
        edge() {}
        edge(int x,int y,int c):u(x),v(y),len(c) {}
    };
    edge p[100005];
    
    struct node
    {
        int po;
        int g,h;
        node() {}
        node(int x,int y,int z):po(x),g(y),h(z) {}
        bool operator<(const node& a)const
        {
            return g+h>a.g+a.h;
        }
    };
    
    void add_edge(int u,int v,int c)
    {
        p[tot] = edge(u,v,c);
        p[tot].next = head[u];
        head[u] = tot;
        p[tot].next1 = head1[v];
        head1[v] = tot++;
    }
    
    void  work(int c)       //从to开始找出所有点到to的最短路
    {
        priority_queue<node>que;
        memset(vis,0,sizeof(vis));
        for(int i = 1; i <= n; i++)
            low[i] = INF;
        low[c] = 0;
        que.push(node(c,0,0));
        while(!que.empty())
        {
            node cur = que.top();
            que.pop();
            if(vis[cur.po])
                continue;
            vis[cur.po] = 1;
            for(int i = head1[cur.po]; ~i; i = p[i].next1)       //反向查找
            {
                if(low[p[i].u] > low[cur.po]+p[i].len)
                {
                    low[p[i].u] = low[cur.po] + p[i].len;
                    que.push(node(p[i].u,0,low[p[i].u]));
                }
            }
        }
    }
    
    
    int bfs(int t)
    {
        int num = 0;
        priority_queue<node>que;
        node cur;
        cur.po = t;
        cur.g = 0;
        que.push(cur);
        while(!que.empty())
        {
            cur = que.top();
            que.pop();
            int tp = cur.po;
            if(tp == to)
            {
                num ++;
                if(num == k)
                {
                    return cur.g;
                }
            }
            for(int i = head[cur.po]; ~i; i = p[i].next)
            {
                node tmp;
                int x = p[i].v;
                tmp.po = x;
                tmp.g = cur.g + p[i].len;
                tmp.h = low[x];
                que.push(tmp);
            }
        }
        return -1;
    }
    
    void ini()
    {
        tot = 0;
        memset(head,-1,sizeof(head));
        memset(head1,-1,sizeof(head1));
    }
    
    int main()
    {
        int a,b,len;
        while(scanf("%d%d",&n,&m) != EOF)
        {
            ini();
    
            for(int i = 0; i < m; i++)
            {
                scanf("%d%d%d",&a,&b,&len);
                add_edge(a,b,len);
            }
            scanf("%d%d%d",&from,&to,&k);
            work(to);
            if(low[from] == INF)   //如果from不能到达to
            {
                printf("-1
    ");
                continue;
            }
            if(from == to)
            {
                k++;
            }
            printf("%d
    ",bfs(from));
        }
        return 0;
    }
    

      

  • 相关阅读:
    问题 L: Robots
    最强阵容
    [学习][Math]康托展开和逆康托展开
    [学习][STL]next_permutation
    [动态规划][数位dp]F(x)
    [动态规划][数位dp]Bomb
    [动态规划][数位dp]不要62
    [动态规划][树形dp]Bichrome Tree
    [思维]Finite Encyclopedia of Integer Sequences
    [二分答案]gpa
  • 原文地址:https://www.cnblogs.com/Przz/p/5409705.html
Copyright © 2020-2023  润新知