poj 3613 Cow Relays

Cow Relays

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 5411   Accepted: 2153

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: NTS, 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

n次floyd,原来flody也能够像矩阵一样高速幂。详细的能够看论文《矩阵乘法在信息学的应用》

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int inf=(1<<30)-1;
int n;
int hash[3010];//映射
struct matrix
{
    int ma[210][210];
    matrix()
    {
       for(int i=0;i<210;i++)
          for(int j=0;j<210;j++)
           ma[i][j]=inf;
    }
};
matrix floyd(matrix x,matrix y)
{
    matrix ans;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int k=1;k<=n;k++)
            ans.ma[i][j]=min(ans.ma[i][j],x.ma[i][k]+y.ma[k][j]);
        }
    }
    return ans;
}
matrix pow(matrix a,int m)
{
    matrix ans;
    for(int i=1;i<=n;i++)
    ans.ma[i][i]=0;
    while(m)
    {
        if(m&1)
        ans=floyd(ans,a);
        a=floyd(a,a);
        m=m>>1;
    }
    return ans;
}
int main()
{
    int k,t,s,e;
    while(~scanf("%d%d%d%d",&k,&t,&s,&e))
    {
        int x,y,d;
        memset(hash,0,sizeof(hash));
        n=1;
        matrix a;
        for(int i=0;i<t;i++)
        {
            scanf("%d%d%d",&d,&x,&y);
            if(!hash[x])
            hash[x]=n++;
            if(!hash[y])
            hash[y]=n++;
            a.ma[hash[x]][hash[y]]=a.ma[hash[y]][hash[x]]=d;
        }
        n=n-1;
        matrix ans;
        ans=pow(a,k);
        printf("%d\n",ans.ma[hash[s]][hash[e]]);
    }
    return 0;
}
时间: 2024-07-28 14:38:28

poj 3613 Cow Relays的相关文章

POJ 3613 Cow Relays 恰好n步的最短路径

http://poj.org/problem?id=3613 题目大意: 有T条路,从s到e走n步,求最短路径. 思路: 看了别人的... 先看一下Floyd的核心思想: edge[i][j]=min(edge[i][j],edge[i][k]+edge[k][j]) i到j的最短路是i到j的直接路径或者经过k点的间接路径,但是矩阵的更新总是受到上一次更新的影响 如果每次的更新都存进新矩阵,那么edge[i][k]+edge[k][j]是不是表示只经过三个点两条边的路径呢? min(edge[i

矩阵十题【十】 poj 3613 Cow Relays

题目链接:http://poj.org/problem?id=3613 题目大意: 输入N,T,S,E,N表示要走的边数,T表示一共有几条边,S表示开始的点,E表示结束的点 给出一张无向连通图,求S到E经过N条边的最短路. N (2 ≤ N ≤ 1,000,000) T (2 ≤ T ≤ 100) (1 ≤ I1i ≤ 1,000; 1 ≤ I2i ≤ 1,000) 1 ≤ lengthi  ≤ 1,000 题目主要的思想就是用矩阵的乘法模拟出Floyd进行运算,是个很好的题目. //k步最短路

POJ 3613 Cow Relays (floyd + 矩阵快速幂)

题目大意: 求刚好经过K条路的最短路 我们知道如果一个矩阵A[i][j] 表示表示 i-j 是否可达 那么 A*A=B  B[i][j]  就表示   i-j 刚好走过两条路的方法数 那么同理 我们把i-j 的路径长度存到A 中. 在A*A的过程中,不断取小的,那么最后得到的也就是i - j 走过两条路的最短路了. 当然也是利用到了floyd的思想. 然后要求出K次的最短路,那么就是矩阵快速幂的工作了. 注意要离散化.用map #include <cstdio> #include <io

POJ 3613 Cow Relays (Floyd + 矩阵快速幂 + 离散化 神题!)

Cow Relays Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5611   Accepted: 2209 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

BZOJ 1706 usaco 2007 Nov relays 奶牛接力跑/POJ 3613 Cow Relays 倍增Floyd

题目大意:求恰好走k步从S到T的最短路. 思路:设f[p][i][j]为从i到j恰好走2^p步的最短路,DP方程十分简单:f[p][i][j] = min(f[p][i][j],f[p - 1][i][k] + f[p - 1][k][j]); 对总步数T进行二进制拆分,在T有1的位置上,假如这个位置为p,那么就用f[p][][]来更新答案g[][],最后得到的g[][]就是答案矩阵. 注意要离散化一下.. CODE: #include <cstdio> #include <cstrin

poj 3613 Cow Relays(矩阵的图论意义)

题解 用一个矩阵来表示一个图的边的存在性,即矩阵C[i,j]=1表示有一条从i到j的有向边C[i,j]=0表示没有从i到j的边.这个矩阵的k次方后C[i,j]就表示有多少条从i到j恰好经过k条边的路径. 在此题中我们赋予边权值并把矩阵乘法中的+改为min这样这个矩阵的k次方后C[i,j]就表示从i到j恰好经过k条边的最短路径. 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include&l

PKU 3613 Cow Relays (指定路径条数的最短路)

题意:N,T,S,E:给你T条边,每条边两端都有编号和权值,问从S走到E允许走N条边,求最短路. foyld加矩阵快速幂思想. 注意要把边离散 #include <iostream> #include <fstream> #include <string.h> #include <algorithm> using namespace std; #define M 303 #define inf 0x3fffffff struct node { int a[M

poj 1985 Cow Marathon 【树的直径】

题目:poj 1985 Cow Marathon 题意:给出一个树,让你求树的直径. 分析: 树的直径:树上两点之间的最大距离. 我们从任意一点出发,BFS一个最远距离,然后从这个点出发,在BFS一个最远距离,就是树的直径. AC代码: /* POJ:1985 Cow Marathon 2014/10/12/21:18 Yougth*/ #include <cstdio> #include <iostream> #include <algorithm> #include

poj 3270 Cow Sorting 置换群 简单题

假设初始状态为 a:2 3 1 5 4 6 则目标状态为 b:1 2 3 4 5 6且下标为初始状态中的3 1 2 4 5 6(a[3],a[1]...) 将置换群写成循环的形式 (2,3,1),(5,4),6就不用移动了. 移动方式2种 1:选循环内最小的数和其他len-1个数交换 2:选整个序列最小的数和循环内最小的数交换,转到1,再换回来. #include<cstdio> #include<queue> #include<algorithm> #include&