zoukankan      html  css  js  c++  java
  • HDU-4511 小明系列故事——女友的考验 floyd变种-标号递增最短路

    题意:给定N个点,现在要求出从1号点到N号点的最短路。题目给的限制条件就是对于某条路径是不能够走的,但是可以选择某段路径走,另外就是所走的路径的标号必须是递增的。

    分析:由于给定的是一些列的坐标点,这也就说原图其实是一个完全图。对于限制路径,其实只要限制的路径上点数超过2,那么明显可以选择从起点直接走到终点这条最短路来代替限制路径,因此该限制不起作用,而对于限制路径上点数为2的路径则需要标记一下不能够取。对于最终路径要求点坐标路径递增这一条件则直接在floyd处理的时候限制好i,j,k三者的关系即可。

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define sqr(x) ((x)*(x))
    using namespace std;
    
    const int N = 55;
    const double eps = 1e-8;
    int n, m;
    int seq[N];
    double mp[N][N];
    
    int sign(const double &x) {
        return x < -eps ? -1 : x > eps ? 1 : 0;
    }
    
    struct Point {
        double x, y;
        bool operator == (const Point &t) const {
            return !sign(x-t.x) && !sign(y-t.y);
        }
    }p[N];
    
    double dist(int a, int b) {
        return sqrt(sqr(p[a].x-p[b].x) + sqr(p[a].y-p[b].y));
    }
    
    void floyd() {
        for (int k = 0; k < n; ++k) {
            for (int i = 0; i < k; ++i) {
                if (!sign(mp[i][k]+1)) continue;
                for (int j = k+1; j < n; ++j) {
                    if (!sign(mp[k][j]+1)) continue;
                    if (!sign(mp[i][j]+1) || sign(mp[i][j]-(mp[i][k]+mp[k][j])) > 0) {
                        mp[i][j] = mp[i][k] + mp[k][j];
                    }
                }
            }
        }
    }
    
    int main() {
        while (scanf("%d %d", &n, &m), n|m) {
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) mp[i][j] = 0;
                scanf("%lf %lf", &p[i].x, &p[i].y);
            }
            int t;
            for (int i = 0; i < m; ++i) {
                scanf("%d", &t);
                for (int j = 0; j < t; ++j) {
                    scanf("%d", &seq[j]);
                }
                if (t == 2 && !(p[seq[0]-1] == p[seq[1]-1])) {
                    mp[seq[0]-1][seq[1]-1] = mp[seq[1]-1][seq[0]-1]= -1;
                }
            }
            for (int i = 0; i < n; ++i) {
                for (int j = i+1; j < n; ++j) {
                    if (sign(mp[i][j]+1)) mp[i][j] = mp[j][i] = dist(i, j);
                }
            }
            floyd();
            if (sign(mp[0][n-1]+1)) printf("%.2f
    ", mp[0][n-1]);
            else puts("Can not be reached!");
        }
        return 0;
    } 
  • 相关阅读:
    CUDA并行算法系列之FFT快速卷积
    CUDA并行算法系列之规约
    混合语言编程:启用CLR(公共语言运行时编译)让C#调用C++
    【CUDA并行程序设计系列(4)】CUDA内存
    【CUDA并行程序设计系列(3)】CUDA线程模型
    【CUDA并行程序设计系列(2)】CUDA简介及CUDA初步编程
    【CUDA并行程序设计系列(1)】GPU技术简介
    关于CUDA的一些学习资料
    MacOS 快捷键技巧
    chrom 自带截屏用法
  • 原文地址:https://www.cnblogs.com/Lyush/p/3351569.html
Copyright © 2011-2022 走看看