POJ --- 3613 (K步最短路+矩阵快速幂+floyd)
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 题意:在无向图中有n条边,现在给出你一个起点S和一个终点E,让你求从S到E经过且仅K条边的最短路径。注意此题中K远大于n,如果K小于n的话直接一边广搜就过了,第一次没注意到这个条件敲了一个BFS,结果WA了。 思路:此题正解应该是矩阵乘法,但是重定义了,区别于线性代数里面的乘法(其实可以看出无论哪种定义,只要能推出矩阵在该定义下满足交换律即可,因为可以用快速幂来加速)。
设原图G对应的邻接矩阵为M,则M的k次幂中M[i][j]就表示从i点到j点经过k条边路径的个数!那么只需要重新定义一下矩阵乘法:M[i][j]表示从i点到j点的的最短路径长度,即M[i][j] = min(M[i][j],M[i][k]+M[k][j])(这个就是floyd算法的核心,DP思想),可以证明该定义满足交换律,因此可以用快速幂,考虑M^2,它表示从i到j经过2条边的最短路径,同理推出M^n表示从i到j经过n条边的最短路径,因此本题得解。
关于矩阵乘法的应用是参考2008年国家集训队论文《矩阵乘法在信息学中的应用》(俞华程)中看到的,网上此题解法大都参考该论文,在网上看了别人解释的没怎么看懂,直接看论文去了,发现论文里面讲的很明白也很透彻,但是经过别人转述意思可能就不一样了,其实我也说的不怎么清楚,所以建议直接去看论文。
网盘下载地址:http://yunpan.cn/QNeFIw2wIef4B (访问密码:7b0c)
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 111
using namespace std;
class Matrix{
public:
int m[MAXN][MAXN];
Matrix(){
memset(m, -, sizeof(m));
}
};
int N = ;
Matrix mtMul(Matrix A, Matrix B){
Matrix tmp;
for(int i = ;i < N;i ++)
for(int j = ;j < N;j ++)
for(int k = ;k < N;k ++){
if(A.m[i][k] == - || B.m[k][j] == -) continue;
int temp = A.m[i][k] + B.m[k][j];
if(tmp.m[i][j] == - || tmp.m[i][j] > temp) tmp.m[i][j] = temp;
}
return tmp;
}
Matrix mtPow(Matrix A, int k){
if(k == ) return A;
Matrix tmp = mtPow(A, k >> );
Matrix res = mtMul(tmp, tmp);
if(k & ) res = mtMul(res, A);
return res;
}
int main(){
int cnt[];
int n, t, s, e;
int u, v, w;
/* freopen("in.c", "r", stdin); */
while(~scanf("%d%d%d%d", &n, &t, &s, &e)){
N = ;
Matrix G;
memset(cnt, -, sizeof(cnt));
for(int i = ;i < t;i ++){
scanf("%d%d%d", &w, &u, &v);
if(cnt[u] == -) cnt[u] = N++;
if(cnt[v] == -) cnt[v] = N++;
G.m[cnt[u]][cnt[v]] = w;
G.m[cnt[v]][cnt[u]] = w;
}
Matrix tmp = mtPow(G, n);
printf("%d\n",tmp.m[cnt[s]][cnt[e]]);
}
return ;
}
另外附上BFS的错误代码:
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#define MAXN 1111
using namespace std;
class Status{
public:
int pre, w, cnt;
bool operator < (const Status &a) const{
return w < a.w;
}
};
typedef struct{
int to, next, w;
}Edge;
Edge edge[];
priority_queue<Status>q;
int head[MAXN], N, T, S, E;
void addedge(int u, int v, int w, int k){
edge[k].to = v;
edge[k].next = head[u];
edge[k].w = w;
head[u] = k++;
edge[k].to = u;
edge[k].next = head[v];
edge[k].w = w;
head[v] = k;
}
void bfs(int s){
while(!q.empty()) q.pop();
Status tmp;
tmp.pre = s;
tmp.w = tmp.cnt = ;
q.push(tmp);
while(!q.empty()){
Status p = q.top();
int v = p.pre;
q.pop();
for(int i = head[v]; ~i; i = edge[i].next){
int u = edge[i].to;
if(u == E && p.cnt+ == N){
printf("%d\n", p.w+edge[i].w);
return;
}else if(u != E){
Status t;
t.pre = u;
t.w = p.w+edge[i].w;
t.cnt = p.cnt+;
q.push(t);
}
}
}
}
int main(){
int length, u, v, k;
/* freopen("in.c", "r", stdin); */
while(~scanf("%d%d%d%d", &N, &T, &S, &E)){
memset(head, -, sizeof(head));
k = ;
for(int i = ; i < T; i ++){
scanf("%d%d%d", &length, &u, &v);
addedge(u, v, length, k);
k += ;
}
bfs(S);
}
return ;
}
POJ --- 3613 (K步最短路+矩阵快速幂+floyd)的更多相关文章
- poj3613Cow Relays——k边最短路(矩阵快速幂)
题目:http://poj.org/problem?id=3613 题意就是求从起点到终点的一条恰好经过k条边的最短路: floyd+矩阵快速幂,矩阵中的第i行第j列表示从i到j的最短路,矩阵本身代表 ...
- poj 3613 Cow Relays【矩阵快速幂+Floyd】
!:自环也算一条路径 矩阵快速幂,把矩阵乘法的部分替换成Floyd(只用一个点扩张),这样每"乘"一次,就是经过增加一条边的最短路,用矩阵快速幂优化,然后因为边数是100级别的,所 ...
- POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂
这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...
- POJ 3233 Matrix Power Series (矩阵快速幂+二分求解)
题意:求S=(A+A^2+A^3+...+A^k)%m的和 方法一:二分求解S=A+A^2+...+A^k若k为奇数:S=(A+A^2+...+A^(k/2))+A^(k/2)*(A+A^2+...+ ...
- poj 3735 Training little cats(矩阵快速幂,模版更权威,这题数据很坑)
题目 矩阵快速幂,这里的模版就是计算A^n的,A为矩阵. 之前的矩阵快速幂貌似还是个更通用一些. 下面的题目解释来自 我只想做一个努力的人 @@@请注意 ,单位矩阵最初构造 行和列都要是(猫咪数+1) ...
- POJ 3233 Matrix Power Series (矩阵快速幂)
题目链接 Description Given a n × n matrix A and a positive integer k, find the sum S = A + A^2 + A^3 + - ...
- POJ 3233 Matrix Power Series(矩阵快速幂)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 19338 Accepted: 8161 ...
- 题解报告:poj 3233 Matrix Power Series(矩阵快速幂)
题目链接:http://poj.org/problem?id=3233 Description Given a n × n matrix A and a positive integer k, fin ...
- 图论专题训练1-D(K步最短路,矩阵连乘)
题目链接 /* *题目大意: *求出从i到j,刚好经过k条边的最短路; * *矩阵乘法的应用之一(国家队论文): *矩阵乘法不满足交换律,矩阵乘法满足结合律; *给定一个有向图,问从A点恰好走k步(允 ...
随机推荐
- 关于$.fn
今天看一篇文章,里面的一段代码出现了$.fn,第一次见到这样的写法,于是跑去问度娘...代码如下: $.fn.scrollUnique = function() { return $(this).ea ...
- 创建安全的ashx文件,ashx编译
<%@ WebHandler Language="C#" Class="Handler2" %> using System; using Syste ...
- 前端资源多个产品整站一键打包&包版本管理(二)——如何在bower的配置文件加上注释
问题: 当一个工程里面有好几个项目,每个项目引用同一个包,但是不同的名字,例如在bower中 fancybox 跟 jquery.fancybox 是一样的,我们只需要下载其中的一个版本,而打包工作不 ...
- ZeroMQ/jzmq安装使用
环境: No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 12.04.2 LTS Release: 12 ...
- Python 基础篇:数据类型、数据运算、表达
1. 数据类型 1.1 数字 int(整型) 在32位机器上,整数的位数为32位,取值范围为-231-231-1,即-2147483648-2147483647 在64位系统上,整数的位数为64位,取 ...
- 在jsp中运用ajax实现同一界面不跳转处理事件
目前,编写应用程序时有两种基本的选择: 桌面应用程序 Web应用程序 它们有什么区别呢?桌面应用程序一般很快(就在您的计算机上运行,不用等待互联网连接),具有漂亮的用户界面(通常和操作系统有关)和非凡 ...
- 转载:STM32之中断与事件---中断与事件的区别
这张图是一条外部中断线或外部事件线的示意图,图中信号线上划有一条斜线,旁边标志19字样的注释,表示这样的线路共有19套.图中的蓝色虚线箭头,标出了外部中断信号的传输路径,首先外部信号从编号1的芯片管脚 ...
- CODEVS 1090 加分二叉树
题目描述 Description 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第j个节点的分数为di, ...
- Collection和Collections的区别
Collection 是集合类的上级接口,继承它的接口主要有set和list.Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索,排序,线程安全化等操作.
- char型字符串(数组)与string型字符串 指针与引用
一.常指针: int *const p; //指针不可改变,但是指针指向的数据可以改变. 指向常量的指针: const int *p; //指针可以改变,但是指针指向的数据不可以改变. 指 ...