zoukankan      html  css  js  c++  java
  • 7-13 天梯地图

    思路

    这题我用了两种写法,我们把数据分层读入就可以调用两次dijkstra而不用重写了。

    第一种是优化的dijkstra,Node节点中只放id和dis的原因是,没有必要放cost,也就是题中的第二个排序的权值。

    对于点A来说,假设B、C两点的dis相同,但是cost[b] < cost[c] ,假如B先到,然后优先队列里面C到了,这样C不能更新cost。假如C先到,则后到的B可以更新cost,这样其实没分别,所以Node里面没有必要放cost。

    堆优化

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=505;
    const int INF=0x3f3f3f3f;
    int d[maxn],dp[maxn],pre[maxn];
    int vis[maxn];
    int n;
    vector<int> path[2];
    
    struct Node {
        int id;
        int dis;
        Node(int i,int c):id(i), dis(c) {}
        bool operator < (const Node& a) const {
            return dis>a.dis;
        }
    };
    
    int dijkstra(int s,int e,vector<int>* g,vector<int>* dist,vector<int>* cast,int index) {
        memset(vis,0,sizeof(vis));
        memset(d,INF,sizeof(d));
        memset(dp,INF,sizeof(dp));
        memset(pre,-1,sizeof(pre));
        d[s]=0;
        dp[s]=0;
        priority_queue<Node> pq;
        pq.push(Node(s,0));
        while (!pq.empty()) {
            Node f=pq.top();
            pq.pop();
            if (vis[f.id]) {
                continue;
            }
            vis[f.id]=1;
            int from=f.id;
            int sz=g[from].size();
            for (int j=0;j<sz;j++) {
                int next=g[from][j];
                if (vis[next]) {
                    continue;
                }
                int ds=dist[from][j];
                int cost=cast[from][j];
                if (d[from]+ds<d[next]) {
                    d[next]=d[from]+ds;
                    dp[next]=dp[from]+cost;
                    pre[next]=from;
                    pq.push(Node(next,d[next]));
                }
                else if (d[from]+ds==d[next]&&dp[from]+cost<dp[next]) {
                    dp[next]=dp[from]+cost;
                    pre[next]=from;
                }
            }
        }
        int root=e;
        while (root!=-1) {
            path[index].push_back(root);
            root=pre[root];
        }
        return d[e];
    }
    
    void printPath(vector<int> pa) {
        int sz=pa.size();
        int print=0;
        for (int i=sz-1;i>=0;i--) {
            if (!print) {
                print=1;
            }
            else {
                printf(" =>");
            }
            printf(" %d",pa[i]);
        }
        printf("
    ");
    }
    
    int main()
    {
        vector<int> g[4][maxn];
        int m,v1,v2,oneway,length,time;
        scanf("%d%d",&n,&m);
        while (m--) {
            scanf("%d%d%d%d%d",&v1,&v2,&oneway,&length,&time);
            g[0][v1].push_back(v2);
            g[1][v1].push_back(length);
            g[2][v1].push_back(time);
            g[3][v1].push_back(1);
            if (!oneway) {
                g[0][v2].push_back(v1);
                g[1][v2].push_back(length);
                g[2][v2].push_back(time);
                g[3][v2].push_back(1);
            }
        }
        int s,e;
        scanf("%d%d",&s,&e);
        int anstime=dijkstra(s,e,g[0],g[2],g[1],0);
        int ansdis=dijkstra(s,e,g[0],g[1],g[3],1);
        if (path[0]==path[1]) {
            printf("Time = %d; Distance = %d:",anstime,ansdis);
            printPath(path[0]);
        }
        else {
            printf("Time = %d:",anstime);
            printPath(path[0]);
            printf("Distance = %d:",ansdis);
            printPath(path[1]);
        }
    
        return 0;
    }
    

    普通dijkstra

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=505;
    const int INF=0x3f3f3f3f;
    int d[maxn],dp[maxn],pre[maxn];
    int vis[maxn];
    int n;
    vector<int> path[2];
    
    struct Node {
        int id;
        int dis;
        Node(int i,int c):id(i), dis(c) {}
        bool operator < (const Node& a) const {
            return dis>a.dis;
        }
    };
    
    int dijkstra(int s,int e,vector<int>* g,vector<int>* dist,vector<int>* cast,int index) {
        memset(vis,0,sizeof(vis));
        memset(d,INF,sizeof(d));
        memset(dp,INF,sizeof(dp));
        memset(pre,-1,sizeof(pre));
        d[s]=0;
        dp[s]=0;
        for (int i=1;i<=n;i++) {
            int from=-1,tmp=INF;
            for (int j=0;j<n;j++) {
                if (!vis[j]&&d[j]<tmp){
                    tmp=d[j];
                    from=j;
                }
            }
            if (from==-1){
                break;
            }
            vis[from]=1;
            int sz=g[from].size();
            for (int j=0;j<sz;j++) {
                int next=g[from][j];
                if (vis[next]) {
                    continue;
                }
                int ds=dist[from][j];
                int cost=cast[from][j];
                if (d[from]+ds<d[next]) {
                    d[next]=d[from]+ds;
                    dp[next]=dp[from]+cost;
                    pre[next]=from;
                }
                else if (d[from]+ds==d[next]&&dp[from]+cost<dp[next]) {
                    dp[next]=dp[from]+cost;
                    pre[next]=from;
                }
            }
        }
        int root=e;
        while (root!=-1) {
            path[index].push_back(root);
            root=pre[root];
        }
        return d[e];
    }
    
    void printPath(vector<int> pa) {
        int sz=pa.size();
        int print=0;
        for (int i=sz-1;i>=0;i--) {
            if (!print) {
                print=1;
            }
            else {
                printf(" =>");
            }
            printf(" %d",pa[i]);
        }
        printf("
    ");
    }
    
    int main()
    {
        vector<int> g[4][maxn];
        int m,v1,v2,oneway,length,time;
        scanf("%d%d",&n,&m);
        while (m--) {
            scanf("%d%d%d%d%d",&v1,&v2,&oneway,&length,&time);
            g[0][v1].push_back(v2);
            g[1][v1].push_back(length);
            g[2][v1].push_back(time);
            g[3][v1].push_back(1);
            if (!oneway) {
                g[0][v2].push_back(v1);
                g[1][v2].push_back(length);
                g[2][v2].push_back(time);
                g[3][v2].push_back(1);
            }
        }
        int s,e;
        scanf("%d%d",&s,&e);
        int anstime=dijkstra(s,e,g[0],g[2],g[1],0);
        int ansdis=dijkstra(s,e,g[0],g[1],g[3],1);
        if (path[0]==path[1]) {
            printf("Time = %d; Distance = %d:",anstime,ansdis);
            printPath(path[0]);
        }
        else {
            printf("Time = %d:",anstime);
            printPath(path[0]);
            printf("Distance = %d:",ansdis);
            printPath(path[1]);
        }
    
        return 0;
    }
    
    
  • 相关阅读:
    数据持久化编程学习总结
    Boost Replaceable by C++11 language features or libraries
    【敬业福bug】支付宝五福卡敬业福太难求 被炒至200元
    由文字生成path后制作写字的动画
    CSS经典布局之弹性布局
    HDU2082 找单词 【母函数】
    HDOJ 题目2475 Box(link cut tree去点找祖先)
    DELPHI中MDI子窗口的关闭 和打开
    sql语句中日期相减的操作
    Delphi编码规范
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/12322326.html
Copyright © 2011-2022 走看看