zoukankan      html  css  js  c++  java
  • 2D poj Cow Relays——folyd+矩阵快速幂

    题目

    For their physical fitness program, (N (2 ≤ N ≤ 1,000,000)) cows have decided to run a relay race using the (T (2 ≤ T ≤ 100)) cow trails throughout the pasture.

    Each trail connects two different intersections ((1 ≤ I_{1i} ≤ 1,000; 1 ≤ I_{2i} ≤ 1,000)), each of which is the termination for at least two trails. The cows know the lengthi of each trail ((1 ≤ length_i ≤ 1,000)), the two intersections the trail connects, and they know that no two intersections are directly connected by two different trails. The trails form a structure known mathematically as a graph.

    To run the relay, the N cows position themselves at various intersections (some intersections might have more than one cow). They must position themselves properly so that they can hand off the baton cow-by-cow and end up at the proper finishing place.

    Write a program to help position the cows. Find the shortest path that connects the starting intersection (S) and the ending intersection (E) and traverses exactly N cow trails.

    Input

    • Line 1: Four space-separated integers: N, T, S, and E
    • Lines 2..T+1: Line i+1 describes trail i with three space-separated integers: (length_i) , (I_{1i}) , and (I_{2i})

    Output

    • Line 1: A single integer that is the shortest distance from intersection S to intersection E that traverses exactly N cow trails.

    Sample Input

    2 6 6 4
    11 4 6
    4 4 8
    8 4 9
    6 6 8
    2 6 9
    3 8 9
    

    Sample Output

    10
    

    题解

    解题思路

    看见数据范围,边的数量不大于100,那么点的数量也就不到100,既然是最短路,那就想到Folyd算法

    //板子
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                f[i][j] = min(f[i][j], f[i][k] + f[k][j])
    

    这个很简单

    然后,我们假设a数组是通过了x条边的最短路,b数组是通过了y条边的最短路

    for(int k = 1; k <= tot; k++)
        for(int i = 1; i <= tot; i++)
            for(int j = 1; j <= tot; j++)
                c[i][j] = min(c[i][j], a[i][k] + b[k][j]);
    

    通过这样,显然我们就得到了c数组是通过了(x+y)条边的最短路

    要经过N条边,就是对原来的邻接矩阵进行N-1操作就行

    矩阵快速幂
    我们把每一次操作看成一次矩阵乘法,就可以用矩阵快速幂来优化

    快速幂

    int qpow(int a, int x) {
        int ans = a;
        x--;
        while (x) {
            if (x & 1) ans *= a;
            x >>= 1;
            a *= a;
        }
        return ans;
    }
    

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int n, k, s, t, m[1005], tot;
    struct node {
        int a[105][105];
        node operator * (const node& b) const {
            node c;
            memset(c.a, 0x3f, sizeof(c.a));
            for(int k = 1; k <= tot; k++)
                for(int i = 1; i <= tot; i++)
                    for(int j = 1; j <= tot; j++)
                        c.a[i][j] = min(c.a[i][j], a[i][k] + b.a[k][j]);
            return c;
        }//重载运算符 * 
    }a;//定义矩阵结构体
    node qpow(node a, int x) {
        node ans = a;
        x--;
        while (x) {
            if (x & 1) ans = ans * a;
            x >>= 1;
            a = a * a;
        }
        return ans;
    }//快速幂
    int main() {
        memset(a.a, 0x3f, sizeof(a.a));
        scanf("%d%d%d%d", &k, &n, &s, &t);
        for(int i = 1, x, y, z; i <= n; i++) {
            scanf("%d%d%d", &z, &x, &y);
            if (!m[x]) m[x] = ++tot;
            if (!m[y]) m[y] = ++tot;
            //这里是离散化
            a.a[m[x]][m[y]] = a.a[m[y]][m[x]] = z;
        }
        a = qpow(a, k);
        printf("%d", a.a[m[s]][m[t]]);
        //注意已经进行了离散化
        return 0;
    }
    
  • 相关阅读:
    变量的生命周期【CPP】
    cpp静态成员和普通成员
    MAVEN学习(二) Myeclipse简单maven项目搭建
    redis安装和部署
    MAVEN学习(三) Maven构建多模块项目
    redis常用客户端命令
    本地计算机如何连接阿里云Mysql数据库
    MAVEN学习(一) nexus私服
    Linux之系统目录结构
    .net开发常用的第三方开发组件
  • 原文地址:https://www.cnblogs.com/Z8875/p/12793956.html
Copyright © 2011-2022 走看看