zoukankan      html  css  js  c++  java
  • poj3613Cow Relays

    Cow Relays
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 7683   Accepted: 3017

    Description

    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 ≤ I1i ≤ 1,000; 1 ≤ I2i ≤ 1,000), each of which is the termination for at least two trails. The cows know the lengthi of each trail (1 ≤ lengthi  ≤ 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: lengthi , I1i , and I2i

    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

    Source

    题意:求从s到e恰好经过n个点的最短路。
    分析:给我的第一印象就是暴力,想dp但没啥思路,没想到还用更厉害的做法。
    预备知识:《矩阵乘法在信息学中的应用》,主要是看邻接矩阵那一块,可以发现,我们可以把图用邻接矩阵的方式存起来,那么a[i][j]就是i到j的路径长度,这是读入后存起来的矩阵,其中每两个点之间的路径不经过其它的点,如果我们将它和自己相乘,就会得到一个新矩阵,其实a[i][j]就是i到j经过1个点的最短路径,当然,直接乘是不能得到最短路径的,我们需要floyd算法。
         可是这个N这么大,意味着我们要做n-1次floyd,这个复杂度妥妥的TLE啊,但是因为这个矩阵每次都和自己相乘,所以可以想到利用快速幂,这里套用快速幂的算法即可。
         还有一个问题:点数有点大,数组可能会开不下,那么怎么做呢?很简单,离散化即可.
    #include <cstring>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    
    #define inf 0x7ffffff  
    
    using namespace std;
    
    int n, t, s, e,ans[210][210],a[210][210],d[210][210],cnt,lisan[100000],temp[210][210];
    
    void floyd1()
    {
        for (int k = 1; k <= cnt; k++)
            for (int i = 1; i <= cnt; i++)
                for (int j = 1; j <= cnt; j++)
                    d[i][j] = min(ans[i][k] + a[k][j], d[i][j]);
        memcpy(ans, d, sizeof(ans));
        memset(d, 0x3f, sizeof(d));
    }
    
    void floyd2()
    {
        for (int k = 1; k <= cnt; k++)
            for (int i = 1; i <= cnt; i++)
                for (int j = 1; j <= cnt; j++)
                    temp[i][j] = min(temp[i][j], a[i][k] + a[k][j]);
        memcpy(a, temp, sizeof(a));
        memset(temp, 0x3f, sizeof(temp));
    }
    
    int main()
    {
        scanf("%d%d%d%d", &n, &t, &s, &e);
        memset(ans, 0x3f, sizeof(ans));
        memset(a, 0x3f, sizeof(a));
        memset(d, 0x3f, sizeof(d));
        memset(temp, 0x3f, sizeof(temp));
        for (int i = 1; i <= 200; i++)
            ans[i][i] = 0;
        for (int i = 1; i <= t; i++)
        {
            int w, x, y;
            scanf("%d%d%d", &w, &x, &y);
            if (!lisan[x])
                lisan[x] = ++cnt;
            if (!lisan[y])
                lisan[y] = ++cnt;
            a[lisan[x]][lisan[y]] = a[lisan[y]][lisan[x]] = min(a[lisan[x]][lisan[y]], w);
        }
        while (n)
        {
            if (n & 1)
                floyd1();
            floyd2();
            n >>= 1;
        }
        printf("%d
    ", ans[lisan[s]][lisan[e]]);
    
        //while (1);
        return 0;
    }


    floyd算法初始化弄错了,WA了几次,智障地发现每个点和自己的路径长度竟然初始化成了inf,TAT.

     
  • 相关阅读:
    使群辉支持NTFS(未完善)
    docker 解决 Dockerfile同级文件有其他文件 导致docker build包越来越大
    nginx location配置前后端地址
    前端 Umi框架自带的proxy功能请求后端地址
    linux常用命令
    arthas的使用(正常部署+服务docker部署)
    linux
    oracle行转列,列转行函数的使用(listagg,xmlagg)
    oracle 使用函数 ROW_NUMBER() OVER(PARTITION BY 列 ORDER BY 列 排序 ),自关联日志表,将列数据转换为 行数据
    oracle merge into用法
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7095315.html
Copyright © 2011-2022 走看看