zoukankan      html  css  js  c++  java
  • ZOJ3088 Easter Holidays 最短路

    题意:给定同一个图上的两种路径,求出从某点出发到另一点的路径长度来回长度之比最大的情况。该题对两套图的处理让代码十分恶心,而且最后还要输出路径。计算出最优值最后在计算一次路径,幸好没有要求在相同的情况下按照字典序最小输出。

    代码如下:

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    int N, M, K;
    struct Edge {
        int v, ct, next;
    }e[1005], re[1005];
    int idx, ridx, head[1005], rhead[1005];
    
    int path[1005];
    int dis[1005][1005];
    int rdis[1005][1005];
    bool vis[1005];
    
    void insert(int a, int b, int ct, Edge e[], int head[], int &idx) {
        ++idx;
        e[idx].v = b, e[idx].ct = ct;
        e[idx].next = head[a];
        head[a] = idx;
    }
    
    void spfa(int sta, int dis[], Edge e[], int head[], int fn) {
        if (fn == 1) {
            memset(dis, 0, sizeof (int) * 1005);
        } else {
            memset(dis, 0x3f, sizeof (int) * 1005);
        }
        memset(vis, 0, sizeof (vis));
        queue<int>q;
        dis[sta] = 0;
        vis[sta] = true;
        q.push(sta);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            vis[v] = false;
            for (int i = head[v]; i != -1; i = e[i].next) {
                if (fn == 1) { // 下坡 
                    if (dis[e[i].v] < dis[v] + e[i].ct) {
                        dis[e[i].v] = dis[v] + e[i].ct;
                        if (!vis[e[i].v]) {
                            q.push(e[i].v);
                            vis[e[i].v] = true;
                        }
                    }
                } else {
                    if (dis[e[i].v] > dis[v] + e[i].ct) {
                        dis[e[i].v] = dis[v] + e[i].ct;
                        if (!vis[e[i].v]) {
                            q.push(e[i].v);
                            vis[e[i].v] = true;
                        }
                    }    
                }
            }
        }
    }
    
    void spfa_path(int sta, int dis[], Edge e[], int head[], int fn) {
        if (fn == 1) {
            memset(dis, 0, sizeof (int) * 1005);
        } else {
            memset(dis, 0x3f, sizeof (int) * 1005);
        }
        memset(path, 0xff, sizeof (path));
        memset(vis, 0, sizeof (vis));
        queue<int>q;
        dis[sta] = 0;
        vis[sta] = true;
        q.push(sta);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            vis[v] = false;
            for (int i = head[v]; i != -1; i = e[i].next) {
                if (fn == 1) { // 下坡 
                    if (dis[e[i].v] < dis[v] + e[i].ct) {
                        dis[e[i].v] = dis[v] + e[i].ct;
                        path[e[i].v] = v;
                        if (!vis[e[i].v]) {
                            q.push(e[i].v);
                            vis[e[i].v] = true;
                        }
                    }
                } else {
                    if (dis[e[i].v] > dis[v] + e[i].ct) {
                        dis[e[i].v] = dis[v] + e[i].ct;
                        path[e[i].v] = v;
                        if (!vis[e[i].v]) {
                            q.push(e[i].v);
                            vis[e[i].v] = true;
                        }
                    }    
                }
            }
        }    
    }
    
    void prt(int x, int &first) {
        if (path[x] != -1) {
            prt(path[x], first);    
        } 
        if (first) {
            printf("%d", x);
            first = 0;
        } else {
            printf(" %d", x);    
        }
    }
    
    int main() {
        int T;
        cin >> T;
        while (T--) {
            idx = ridx = -1;
            memset(head, 0xff, sizeof (head));
            memset(rhead, 0xff, sizeof (rhead));
            int a, b, c;
            cin >> N >> M >> K;
            // M条下坡的边 
            for (int i = 0; i < M; ++i) {
                scanf("%d %d %d", &a, &b, &c);
                insert(a, b, c, e, head, idx);
            }
            // K条上山的边
            for (int i = 0; i < K; ++i) {
                scanf("%d %d %d", &a, &b, &c);
                insert(a, b, c, re, rhead, ridx);
            }
            for (int i = 1; i <= N; ++i) {
                spfa(i, dis[i], e, head, 1);     // 下坡运算
                spfa(i, rdis[i], re, rhead, 2); // 上坡运算
            }
            double Max = 0;
            int x, y; 
            for (int i = 1; i <= N; ++i) {
                for (int j = 1; j <= N; ++j) {
                    if (rdis[j][i] != 0) {
                        if (1.0*dis[i][j]/rdis[j][i] > Max) {
                            x = i, y = j;
                            Max = max(1.0*dis[i][j]/rdis[j][i], Max);
                        }
                    }
                }
            }
            int first = 1;
            spfa_path(y, rdis[x], re, rhead, 2);
            prt(path[x], first);
            spfa_path(x, dis[x], e, head, 1);
            prt(y, first);
            printf("\n%.3f\n", Max);
        }
        return 0;    
    } 
  • 相关阅读:
    Laravel使用Eloquent ORM操作数据库
    Laravel查询构造器的使用方法整理
    [wordpress]后台自定义菜单字段和使用wordpress color picker
    Thinkphp kindeditor 内容转义
    WordPress 后台提示输入FTP信息
    [记录]gulp compass
    symonfy 项目根目录下没有 bin/console 文件的解决方法
    [gulp] gulp lint 忽略文件
    [转载]ubuntu Atheros Communications Device 1083 驱动
    SharpDevelop 编译时,任务失败,因为未找到“resgen.exe”的解决方法
  • 原文地址:https://www.cnblogs.com/Lyush/p/2950847.html
Copyright © 2011-2022 走看看