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.

     
  • 相关阅读:
    【数学】三分法
    【数学】【背包】【NOIP2018】P5020 货币系统
    【数学】【CF27E】 Number With The Given Amount Of Divisors
    【单调队列】【P3957】 跳房子
    【极值问题】【CF33C】 Wonderful Randomized Sum
    【DP】【CF31E】 TV Game
    【神仙题】【CF28D】 Don't fear, DravDe is kind
    【线段树】【CF19D】 Points
    【字符串】KMP字符串匹配
    【二维树状数组】【CF10D】 LCIS
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7095315.html
Copyright © 2011-2022 走看看