zoukankan      html  css  js  c++  java
  • HDU 5636 Shortest Path

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5636

    题解:

    1、暴力枚举:

    #include<cmath>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    typedef long long LL;
    const int maxn = 1e5 + 10;
    const int mod = 1e9 + 7;
    
    int n, m;
    int a[11], b[11];
    
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            scanf("%d%d", &n, &m);
            for (int i = 0; i < 3; i++) scanf("%d%d", a + i, b + i);
            LL ans = 0;
            int x, y;
            for (int i = 1; i <= m; i++) {
                scanf("%d%d", &x, &y);
                //一条新路线都不走
                int tmp = abs(x - y);
            
                //只走一条
                for (int j = 0; j < 3; j++) {
                    tmp = min(tmp, abs(x - a[j]) + abs(b[j] - y) + 1);
                    tmp = min(tmp, abs(x - b[j]) + abs(a[j] - y) + 1);
                }
    
                //走两条
                for (int j = 0; j < 3; j++) {
                    for (int k = 0; k < 3; k++) {
                        if (j == k) continue;
                        //x -> j开头 -> j结尾 -> k开头 -> k结尾 -> y
                        tmp = min(tmp, abs(x - a[j]) + abs(b[j] - a[k]) + abs(b[k] - y) + 2);
                        //x -> j开头 -> j结尾 -> k结尾 -> k开头 -> y
                        tmp = min(tmp, abs(x - a[j]) + abs(b[j] - b[k]) + abs(a[k] - y) + 2);
                        //x -> j结尾 -> j开头 -> k开头 -> k结尾 -> y
                        tmp = min(tmp, abs(x - b[j]) + abs(a[j] - a[k]) + abs(b[k] - y) + 2);
                        //x -> j结尾 -> j开头 -> k结尾 -> k开头 -> y
                        tmp = min(tmp, abs(x - b[j]) + abs(a[j] - b[k]) + abs(a[k] - y) + 2);
                    }
                }
    
                //走三条
                for (int j = 0; j < 3; j++) {
                    for (int k = 0; k < 3; k++) {
                        if (j == k) continue;
                        for (int w = 0; w < 3; w++) {
                            if (w == j || w == k) continue;
                            tmp = min(tmp, abs(x - a[j]) + abs(b[j] - a[k]) + abs(b[k] - a[w]) + abs(b[w] - y) + 3);
                            tmp = min(tmp, abs(x - a[j]) + abs(b[j] - a[k]) + abs(b[k] - b[w]) + abs(a[w] - y) + 3);
                            tmp = min(tmp, abs(x - a[j]) + abs(b[j] - b[k]) + abs(a[k] - a[w]) + abs(b[w] - y) + 3);
                            tmp = min(tmp, abs(x - a[j]) + abs(b[j] - b[k]) + abs(a[k] - b[w]) + abs(a[w] - y) + 3);
    
                            tmp = min(tmp, abs(x - b[j]) + abs(a[j] - a[k]) + abs(b[k] - a[w]) + abs(b[w] - y) + 3);
                            tmp = min(tmp, abs(x - b[j]) + abs(a[j] - a[k]) + abs(b[k] - b[w]) + abs(a[w] - y) + 3);
                            tmp = min(tmp, abs(x - b[j]) + abs(a[j] - b[k]) + abs(a[k] - a[w]) + abs(b[w] - y) + 3);
                            tmp = min(tmp, abs(x - b[j]) + abs(a[j] - b[k]) + abs(a[k] - b[w]) + abs(a[w] - y) + 3);
                        }
                    }
                }
                ans += ((LL)i*tmp)%mod;
                ans %= mod;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code

     2、floyd:

    对三条新边对应的关键顶点重新建图,跑一遍floyd最短路,对于查询(xi,yi),我们枚举任意两个关键节点(aj,bj),求min(|xi-aj|+len+|bj-yi|),其中len表示新图里面aj到bj的最短距离。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 typedef long long LL;
     8 
     9 const int maxn = 1e5 + 10;
    10 const int mod = 1e9 + 7;
    11 const int INF = 0x3f3f3f3f;
    12 
    13 int n, m;
    14 int a[11],mat[11][11];
    15 
    16 void init() {
    17     memset(mat, 0x3f, sizeof(mat));
    18     for (int i = 0; i < 11; i++) mat[i][i] = 0;
    19 }
    20 
    21 int main() {
    22     int tc;
    23     scanf("%d", &tc);
    24     while (tc--) {
    25         init();
    26         scanf("%d%d", &n, &m);
    27         for (int i = 0; i < 3; i++) {
    28             scanf("%d%d", a + i, a + i + 3);
    29         }
    30         //新图
    31         for (int i = 0; i < 6; i++) {
    32             for (int j = 0; j < 6; j++) {
    33                 mat[i][j] = abs(a[i] - a[j]);
    34             }
    35         }
    36         for (int i = 0; i < 3; i++) {
    37             mat[i][i + 3] = mat[i + 3][i] = 1;
    38         }
    39         //floyd
    40         for (int k = 0; k < 6; k++) {
    41             for (int i = 0; i < 6; i++) {
    42                 for (int j = 0; j < 6; j++) {
    43                     mat[i][j] = min(mat[i][j], mat[i][k] + mat[k][j]);
    44                 }
    45             }
    46         }
    47         LL ans = 0;
    48         for (int i = 1; i <= m; i++) {
    49             int x, y;
    50             scanf("%d%d", &x, &y);
    51             LL z = abs(x-y);
    52             //枚举所有情况
    53             for (int i = 0; i < 6; i++) {
    54                 for (int j = 0; j < 6; j++) {
    55                     int tmp = abs(x - a[i]) + mat[i][j] + abs(a[j] - y);
    56                     z = min(z, (LL)tmp);
    57                 }
    58             }
    59             ans += z*i;
    60             ans %= mod;
    61         }
    62         printf("%lld
    ", ans);
    63     }
    64     return 0;
    65 }
    View Code
      
  • 相关阅读:
    C++ Primer注意事项11_运算符重载_算术/关系运算符_下标运算符
    android最新的工具DateHelper
    ssh否password登陆server
    atitit.设计模式(2) -----查询方式/ command 总结
    采用Eclipse中间Maven构建Web项目错误(一)
    dm8148 jpeg编解码器测试
    C++ 结构体和类的区别
    C++ const
    C++中的inline函数
    C++ 模板类demo
  • 原文地址:https://www.cnblogs.com/fenice/p/5246309.html
Copyright © 2011-2022 走看看