zoukankan      html  css  js  c++  java
  • POJ2449题解

    • 先讲一个为了少打一些代码而滥用继承终于接受慘痛教训的故事。
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int oo = 1000000000, nil = 0;
    int N, M, S, T, K, times[1005];
    int u[200010], v[200010], w[200010], nxt[200010], pnt[1005], e;
    int d[1005];
    bool vis[1005], other[1005];
    class node
    {
        public:
            int n, dis;
            node(int n = 0, int dis = 0) :n(n), dis(dis) {}
        protected:
            virtual bool operator < (const node& b) const
            {
                return dis > b.dis;
            }
    };
    struct astar : public node
    {
        astar(int xn = 0, int xdis = 0)
        {
            n = xn; dis = xdis;
        }
        bool operator < (const astar& b) const
        {
            return dis + d[n] > b.dis + d[b.n];
        }
    };
    void addedge(int a, int b, int c, bool d)
    {
        u[++e] = a; v[e] = b; w[e] = c;
        nxt[e] = pnt[a]; pnt[a] = e; other[e] = d;
    }
    void init()
    {
        int a, b, c;
        scanf("%d%d", &N, &M);
        for(int i = 1; i <= M; ++i)
        {
            scanf("%d%d%d", &a, &b, &c);
            addedge(a, b, c, false);
            addedge(b, a, c, true);
        }
        scanf("%d%d%d", &S, &T, &K);
        if(S == T)
        {
            ++K;
        }
    }
    void getSSSP(int s)
    {
        memset(d, 0x3f, sizeof(d));
        memset(vis, 0, sizeof(vis));
        priority_queue <node> Q;
        d[s] = 0;
        Q.push(node(s, 0));
        while(!Q.empty())
        {
            node t = Q.top();
            Q.pop();
            vis[t.n] = true;
            for(int j = pnt[t.n]; j != nil; j = nxt[j])
            {
                if((!vis[v[j]]) && (d[v[j]] > t.dis + w[j]) && (other[j]))
                {
                    d[v[j]] = t.dis + w[j];
                    Q.push(node(v[j], d[v[j]]));
                }
            }
        }
    }
    void work()
    {
        getSSSP(T);
        memset(times, 0, sizeof(times));
        priority_queue <astar> Q;
        Q.push(astar(S, 0));
        while(!Q.empty())
        {
            astar t = Q.top();
            Q.pop();
            ++times[t.n];
            if((t.n == T) && (times[t.n] == K))
            {
                printf("%d
    ", t.dis);
                return;
            }
            for(int j = pnt[t.n]; j != nil; j = nxt[j])
            {
                if(!other[j])
                {
                    Q.push(astar(v[j], t.dis + w[j]));
                }
            }
        }
        puts("-1");
    }
    int main()
    {
        init();
        work();
        return 0;
    }
    

    然后由于node里的小于号被protected了。stl的priority_queue无法调用之而编译失败。

    假设去掉protected。node里的小于号覆盖不掉,又会使astar中的小于号没用导致WA。TUT……

    • 题目来源

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

    • 题目大意
      求一张有向图从S到T的第K短路(边权均为正)。

    • 题解
      首先在反向图中最短路出每一个点到终点的距离,然后利用A*的思想,从起点開始可反复地搜索,估价函数为{当前走过的距离+该点到终点的最短路长度}。当终点T被第K次从堆(优先队列)中取出时,输出答案。

    • 注意细节
      S == T时要把K加上1;
      某结点出队次数超过K时,能够不再考虑。

    • Code

    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int oo = 1000000000, nil = 0;
    int N, M, S, T, K, times[1005];
    int u[200010], v[200010], w[200010], nxt[200010], pnt[1005], e;
    int d[1005];
    bool vis[1005], other[200010];
    struct node
    {
        int n, dis;
        node(int n = 0, int dis = 0) :n(n), dis(dis) {}
        bool operator < (const node& b) const
        {
            return dis > b.dis;
        }
    };
    struct astar
    {
        int n, dis;
        astar(int n = 0, int dis = 0) :n(n), dis(dis) {}
        bool operator < (const astar& b) const
        {
            return dis + d[n] > b.dis + d[b.n];
        }
    };
    void addedge(int a, int b, int c, bool d)
    {
        u[++e] = a; v[e] = b; w[e] = c;
        nxt[e] = pnt[a]; pnt[a] = e; other[e] = d;
    }
    void init()
    {
        int a, b, c;
        scanf("%d%d", &N, &M);
        for(int i = 1; i <= M; ++i)
        {
            scanf("%d%d%d", &a, &b, &c);
            addedge(a, b, c, false);
            addedge(b, a, c, true);
        }
        scanf("%d%d%d", &S, &T, &K);
        if(S == T)
        {
            ++K;
        }
    }
    void getSSSP()
    {
        memset(d, 0x3f, sizeof(d));
        memset(vis, 0, sizeof(vis));
        priority_queue <node> Q;
        d[T] = 0;
        Q.push(node(T, 0));
        while(!Q.empty())
        {
            node t = Q.top();
            Q.pop();
            vis[t.n] = true;
            for(int j = pnt[t.n]; j != nil; j = nxt[j])
            {
                if((!vis[v[j]]) && (d[v[j]] > t.dis + w[j]) && (other[j]))
                {
                    d[v[j]] = t.dis + w[j];
                    Q.push(node(v[j], d[v[j]]));
                }
            }
        }
    }
    void work()
    {
        getSSSP();
        memset(times, 0, sizeof(times));
        priority_queue <astar> Q;
        Q.push(astar(S, 0));
        while(!Q.empty())
        {
            astar t = Q.top();
            Q.pop();
            ++times[t.n];
            if((t.n == T) && (times[t.n] == K))
            {
                printf("%d
    ", t.dis);
                return;
            }
            if(times[t.n] > K)
            {
                continue;
            }
            for(int j = pnt[t.n]; j != nil; j = nxt[j])
            {
                if(!other[j])
                {
                    Q.push(astar(v[j], t.dis + w[j]));
                }
            }
        }
        puts("-1");
    }
    int main()
    {
        init();
        work();
        return 0;
    }
    • 再讲一个悲伤的故事:这段代码我一開始把other数组开成了点数,然后RE了4次,另一次忘了删去while(1)……所以一定要养成提前定义常量和认真静态查错的好习惯。

  • 相关阅读:
    团队管理 - 团队发展五阶段
    信息系统开发平台OpenExpressApp - 支持差异保存
    MDSF:Mendix介绍
    需求入门 - 获取需求方法:Nine Boxes
    个人管理 - 第四代时间管理
    需求入门 - 业务需求分析入门(公司研发峰会演讲ppt)
    个人管理 - Learn More,Study Less!
    如何培养一个人:从育儿谈起
    个人管理 - 如何演讲
    企业架构 - ADM方法概要介绍
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7068329.html
Copyright © 2011-2022 走看看