矩阵十题【十】 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步最短路
 #include<stdio.h>
 #include<string.h>
 #define INF 0x3f3f3f3f
 #define N 101

 struct Matrix
 {
     int edge[N][N];
 }map,tmp,res;

 int n,f[N*10];
 Matrix mul(Matrix x,Matrix y)    //floyd
 {
     memset(tmp.edge,INF,sizeof(tmp.edge));
     int i,j,k;
     for(i=1;i<=n;i++)
         for(j=1;j<=n;j++)
             for(k=1;k<=n;k++)
                 if(tmp.edge[i][j]>x.edge[i][k]+y.edge[k][j])
                     tmp.edge[i][j]=x.edge[i][k]+y.edge[k][j];
     return tmp;
 }
 void quickpow(int k)
 {
     int i;
     memset(res.edge,INF,sizeof(res.edge));
     for(i=1;i<=n;i++)
         res.edge[i][i]=0;
     while(k)    //二进制思想
     {
         if(k&1)
             res=mul(res,map);
         map=mul(map,map);
         k>>=1;
     }
 }
 int main()
 {
     int i,k,t,s,e,len,u,v;
     scanf("%d%d%d%d",&k,&t,&s,&e);
     memset(map.edge,INF,sizeof(map.edge));
     memset(f,-1,sizeof(f));
     int num=0;
     for(i=0;i<t;i++)
     {
         scanf("%d%d%d",&len,&u,&v);
         if(f[u]==-1)    //离散化
             f[u]=++num;
         if(f[v]==-1)    //离散化
             f[v]=++num;
         map.edge[f[u]][f[v]]=map.edge[f[v]][f[u]]=len;
     }
     n=num;
     quickpow(k);
     printf("%d\n",res.edge[f[s]][f[e]]);
     return 0;
 }

矩阵十题【十】 poj 3613 Cow Relays,布布扣,bubuko.com

时间: 2024-10-18 11:35:05

矩阵十题【十】 poj 3613 Cow Relays的相关文章

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 恰好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 (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

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

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

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

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 1575 Tr A 【矩阵】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1575 题目大意:A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. 数据的第一行是一个T,表示有T组数据. 每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据.接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容. 一个矩阵快速幂的裸题. 题解: #include<iostr

矩阵十题【六】 poj3070 Fibonacci

题目链接:http://poj.org/problem?id=3070 题目大意:给定n和10000,求第n个Fibonacci数mod 10000 的值,n不超过2^31.结果保留四位数字. 很简单的题,和之前做过的相比简单很多了. 构造最简单的斐波那契数列矩阵. #include<iostream> #include<cstring> #include<stdio.h> using namespace std; const int MAX = 2; struct M