zoukankan      html  css  js  c++  java
  • uva 10816 Travel in Desert(简单的好题~两种方法)

    题意:

    给出 一个图

    点与点之间的路径上有两个权值 路径长度和温度

    要求在所走路径中的温度的最大值最小的前提下 走最短路径

    解题思路1:

    首先用 最小生成树 的方法走出 最小瓶颈路 。把在这期间用到的全部温度小于 路径上最大温度 的边存下来,作为接下来求最短路径的图。

    在新生成的图中求最短路径就可以;

    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    
    const int maxm = 10005;
    const int maxn = 105;
    
    struct Edge{
        int u,v;
        double dist,tm;
        void read(){
            scanf("%d%d%lf%lf",&u,&v,&tm,&dist);
            u--;v--;
        }
        bool operator<(const Edge et)const{
            if(tm != et.tm) return tm < et.tm;
            else return dist < et.dist;
        }
    }e[maxm];
    int n,m,s,t;
    int parent[maxn];
    vector<Edge> g[maxn];
    
    
    void init(){
        scanf("%d%d",&s,&t);
        s--;t--;
        for(int i = 0; i < m; i++){
            e[i].read();
        }
        for(int i = 0; i < n; i++){
                g[i].clear();
        }
    }
    int find(int x){
        if(parent[x] == x) return x;
        else return parent[x] = find(parent[x]);
    }
    
    
    const int INF = 0x3f3f3f3f;
    const int MAXNODE = 105;
    
    struct Edge2 {
        int u, v;
        double dist;
        Edge2() {}
        Edge2(int u, int v, double dist) {
            this->u = u;
            this->v = v;
            this->dist = dist;
        }
    };
    struct HeapNode {
        double d;
        int u;
        HeapNode() {}
        HeapNode(double d, int u) {
            this->d = d;
            this->u = u;
        }
        bool operator < (const HeapNode& c) const {
            return d > c.d;
        }
    };
    struct Dijkstra {
        int n, m;
        vector<Edge2> edges;
        vector<int> g[MAXNODE];
        bool done[MAXNODE];
        double d[MAXNODE];
        int p[MAXNODE];
    
        void init(int tot) {
            n = tot;
            for (int i = 0; i < n; i++)
                g[i].clear();
            edges.clear();
        }
    
        void add_Edge(int u, int v, double dist) {
            edges.push_back(Edge2(u, v, dist));
            m = edges.size();
            g[u].push_back(m - 1);
        }
    
        void print(int s, int e) {//shun xu
            if (s == e) {
                printf("%d", e + 1);
                return;
            }
            print(s, edges[p[e]].u);
            printf(" %d", e + 1);
        }
    
        void print2(int s, int e) {//ni xu
            if (s == e) {
                printf("%d", e + 1);
                return;
            }
            printf("%d ", e + 1);
            print2(s, edges[p[e]].u);
        }
    
        void dijkstra(int s) {
            priority_queue<HeapNode> Q;
            for (int i = 0; i < n; i++) d[i] = INF*1.0;
            d[s] = 0.0;
            memset(done, false, sizeof(done));
            Q.push(HeapNode(0, s));
            while (!Q.empty()) {
                HeapNode x = Q.top(); Q.pop();
                int u = x.u;
                if (done[u]) continue;
                done[u] = true;
                for (int i = 0; i < g[u].size(); i++) {
                    Edge2& e = edges[g[u][i]];
                    if (d[e.v] > d[u] + e.dist) {
                        d[e.v] = d[u] + e.dist;
                        p[e.v] = g[u][i];
                        Q.push(HeapNode(d[e.v], e.v));
                    }
                }
            }
        }
    } graph;
    
    void solve(){
    //    printf("...
    ");
        double ans = 0;
        sort(e,e+m);
    
    //    for(int i = 0; i < m; i++){
    //        printf("%.1lf %.1lf %d %d
    ",e[i].dist,e[i].tm,e[i].u,e[i].v);
    //    }
        for(int i = 0; i < n; i++) parent[i] = i;
    
        double max_tm = 500.0;
        graph.init(n);
        for(int i = 0; i < m; i++){
            if(e[i].tm > max_tm) break;
            graph.add_Edge(e[i].u,e[i].v,e[i].dist);
            graph.add_Edge(e[i].v,e[i].u,e[i].dist);
    
            int pu = find(e[i].u);
            int pv = find(e[i].v);
            if(pu == pv) continue;
            parent[pu] = pv;
    
            if(find(s) == find(t)){
                max_tm = e[i].tm;
            }
        }
    
        graph.dijkstra(s);
        graph.print(s,t);
        printf("
    ");
        printf("%.1lf %.1lf
    ",graph.d[t],max_tm);
    
    }
    int main(){
        while(scanf("%d%d",&n,&m) != EOF){
            init();
            solve();
        }
        return 0;
    }
    

    解题思路二:

    把原图存下来,然后二分温度,再把全部小于温度mid的边拿出来构成一个新图,然后继续dijkstra求最短路,有成功和不成功两种结果,找到能成功的最小温度就可以

    code

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    using namespace std;
    
    const int MAXNODE = 105;
    const int MAXEDGE = 20005;
    
    typedef double Type;
    const Type INF = 0x3f3f3f3f;
    
    struct Edge {
        int u, v;
        Type dist, d;
        Edge() {}
        Edge(int u, int v, Type dist, Type d = 0) {
            this->u = u;
            this->v = v;
            this->dist = dist;
            this->d = d;
        }
        void read() {
            scanf("%d%d%lf%lf", &u, &v, &d, &dist);
            u--; v--;
        }
    };
    
    struct HeapNode {
        Type d;
        int u;
        HeapNode() {}
        HeapNode(Type d, int u) {
            this->d = d;
            this->u = u;
        }
        bool operator < (const HeapNode& c) const {
            return d > c.d;
        }
    };
    
    int n, m, s, t;
    
    struct Dijkstra {
        int n, m;
        Edge edges[MAXEDGE];
        int first[MAXNODE];
        int next[MAXEDGE];
        bool done[MAXNODE];
        Type d[MAXNODE];
        int p[MAXNODE];
    
        void init(int n) {
            this->n = n;
            memset(first, -1, sizeof(first));
            m = 0;
        }
    
        void add_Edge(int u, int v, Type dist) {
            edges[m] = Edge(u, v, dist);
            next[m] = first[u];
            first[u] = m++;
        }
    
        void add_Edge(Edge e) {
            edges[m] = e;
            next[m] = first[e.u];
            first[e.u] = m++;
        }
        void print(int e) {//shun xu
            if (p[e] == -1) {
                printf("%d", e + 1);
                return;
            }
            print(edges[p[e]].u);
            printf(" %d", e + 1);
        }
    
        void print2(int e) {//ni xu
            if (p[e] == -1) {
                printf("%d
    ", e + 1);
                return;
            }
            printf("%d ", e + 1);
            print2(edges[p[e]].u);
        }
    
        bool dijkstra(int s, int t) {
            priority_queue<HeapNode> Q;
            for (int i = 0; i < n; i++) d[i] = INF;
            d[s] = 0;
            p[s] = -1;
            memset(done, false, sizeof(done));
            Q.push(HeapNode(0, s));
            while (!Q.empty()) {
                HeapNode x = Q.top(); Q.pop();
                int u = x.u;
                if (u == t)
                    return true;
                if (done[u]) continue;
                done[u] = true;
                for (int i = first[u]; i != -1; i = next[i]) {
                    Edge& e = edges[i];
                    if (d[e.v] > d[u] + e.dist) {
                        d[e.v] = d[u] + e.dist;
                        p[e.v] = i;
                        Q.push(HeapNode(d[e.v], e.v));
                    }
                }
            }
            return false;
        }
    } gao;
    
    Edge e[MAXEDGE];
    
    bool judge(double mid) {
        gao.init(n);
        for (int i = 0; i < m; i++) {
            if (e[i].d > mid) continue;
            gao.add_Edge(e[i]);
            gao.add_Edge(Edge(e[i].v, e[i].u, e[i].dist, e[i].d));
        }
        if (gao.dijkstra(s, t)) return true;
        return false;
    }
    
    int main() {
        while (~scanf("%d%d", &n, &m)) {
            scanf("%d%d", &s, &t);
            s--; t--;
            for (int i = 0; i < m; i++)
                e[i].read();
            double l = 0, r = 50, mid;
            while (r - l > 1e-8) {
                mid = (l + r) / 2;
                if (judge(mid)) r = mid;
                else l = mid;
            }
            if (judge(r)) {
                gao.print(t); printf("
    ");
                printf("%.1lf %.1lf
    ", gao.d[t], mid);
            }
        }
        return 0;
    }
    
    二分在非常多情况下都是非常好用的一种方法~


  • 相关阅读:
    Atitit fms Strait (海峡) lst 数据列表目录1. 4大洋 12. 著名的海大约40个,总共约55个海 13. 海区列表 23.1. 、波利尼西亚(Polynesia,
    Atitit trave islands list 旅游资源列表岛屿目录1. 东南亚著名的旅游岛屿 21.1. Cjkv 日韩 冲绳 琉球 济州岛 北海道 21.2. 中国 涠洲岛 南澳
    Atitit Major island groups and archipelagos 主要的岛群和群岛目录资料目录1. 岛群 波利尼西亚(Polynesia, 美拉尼西亚(Melanesia,
    Atitit glb 3tie city lst 三线城市列表 数据目录1. 全球范围内约90个城市 三线 12. 世界性三线城市全球共
    Atitit glb 1tie 2tie city lst 一二线城市列表数据约50个一线城市Alpha ++ 阿尔法++,,London 伦敦,,New York 纽约,,Alpha +
    Attit 现代编程语言重要特性目录第一章 类型系统 基本三大类型 2第一节 字符串 数字 bool 2第二节 推断局部变量 2第三节 动态类型 2第二章 可读性与开发效率 简单性 2
    Atitit 未来数据库新特性展望目录1. 统一的翻页 21.1. 2 Easy Top-N
    使用Chrome DevTools(console ande elements panel)进行xpath/css/js定位
    chrome -console妙用之定位xpath/js/css
    表达式树之构建Lambda表达式
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5417952.html
Copyright © 2011-2022 走看看