博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj3613:Cow Relays(倍增优化+矩阵乘法floyd+快速幂)
阅读量:4982 次
发布时间:2019-06-12

本文共 3626 字,大约阅读时间需要 12 分钟。

Cow Relays

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7825   Accepted: 3068

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 411 4 64 4 88 4 96 6 82 6 93 8 9

Sample Output

10

题意

给出一张图,求k边最短路,即经过k条边的最短路。

分析

思考一下:如果一个矩阵,表示走k条边后,一张图的点与点的最短路径,(a,b)表示从a到b的最短路径,然后我们把它与自己,按照矩阵乘法的格式“相乘”,把其中的乘改为取min,c.a[i][j] = min(c.a[i][j],x.a[i][k]+y.a[k][j]);看不懂先看下面。

 

这样得到的是走k+k条边的矩阵。有点抽象,下面详细解释下:

c中的一个点(a,b),当我们用x矩阵和y矩阵求它时,我们枚举了x矩阵的a行所有数,与y矩阵的b列所有数,并且他们的坐标只能是相对应的,比如x矩阵的(a,2)这个点,相应的y矩阵点就是(2,b),那么放到图上去理解,即从a点经过2点到b点的距离,类似的点不只有2,把所有点枚举完后,c.a[a][b]就是从a到b的最短距离。(意会一下)

这样下来,会得到走k+k条边的最短路径,对于其他的矩阵这样操作,得到的是他们两个,经过的边数相加的结果。(一个经过a条边后的矩阵 与 一个经过b条边后的矩阵这样操作后,是经过a+b条边后的矩阵,矩阵中存的是最短路径)。解释一下:向上面的例子一样,(a,2)(2,b),是即从a点经过2点到b点的距离,因为x矩阵和y矩阵都是走k条边后的最短路径,那么x矩阵中的(a,2)是走k步后的最短路径,(2,b)也是,那么他们相加不就是走k+k条边后的最短路径吗?其他的矩阵一样。

 

然后,就可以套用快速幂的模板了,只不过将以前的乘改成加了,也就是倍增的思想的,比如对于走10条边,它的二进制是1010,那么我们就让在走2(10)边时的矩阵 乘以 8(1000)边的矩阵,得到走10条边的矩阵即开始时由1->2->4->8->16……即倍增中的2次幂。

code

1 #include
2 #include
3 #include
4 #include
5 6 using namespace std; 7 const int MAXN = 210; 8 9 int Hash[1010];10 int n,k,q,z,tn; 11 12 int read()13 {14 int x = 0,f = 1;char ch = getchar();15 while (ch<'0'||ch>'9') {
if (ch='-') f=-1;ch = getchar(); }16 while (ch>='0'&&ch<='9'){x = x*10+ch-'0';ch = getchar(); }17 return x*f;18 }19 20 struct Matrix{21 int a[MAXN][MAXN];22 Matrix operator * (const Matrix &x) const 23 {24 Matrix c;25 memset(c.a,0x3f,sizeof(c.a));26 for (int k=1; k<=tn; k++)27 for (int i=1; i<=tn; ++i)28 for (int j=1; j<=tn; ++j)29 c.a[i][j] = min(c.a[i][j],a[i][k]+x.a[k][j]);30 return c;31 } 32 }s,ans;33 void ksm()34 { 35 ans = s;36 k--;37 for (; k; k>>=1)38 {39 if (k&1) ans = ans*s;40 s = s*s;41 }42 }43 int main()44 {45 k = read();n = read();q = read();z = read();46 memset(s.a,0x3f,sizeof(s.a));47 for (int x,y,w,i=1; i<=n; ++i)48 {49 w = read();x = read();y = read();50 if (!Hash[x]) Hash[x] = ++tn;51 if (!Hash[y]) Hash[y] = ++tn;52 s.a[Hash[x]][Hash[y]] = s.a[Hash[y]][Hash[x]] = w;53 }54 ksm();55 printf("%d",ans.a[Hash[q]][Hash[z]]);56 return 0;57 }

 

转载于:https://www.cnblogs.com/mjtcn/p/7308870.html

你可能感兴趣的文章
c++学习(三):表达式和语句
查看>>
laravel框架基础知识总结
查看>>
nginx: 响应体太大
查看>>
字符串反混淆实战 Dotfuscator 4.9 字符串加密技术应对策略
查看>>
单例模式
查看>>
Robotium源码分析之Instrumentation进阶
查看>>
Android 交错 GridView
查看>>
(2)把BlackBerry作为插件安装到已有的Eclipse中
查看>>
VUE-es6
查看>>
MySQL-5.7 高阶语法及流程控制
查看>>
C++学习笔记(十)——向上造型
查看>>
2017/6/16
查看>>
LeetCode 445——两数相加 II
查看>>
预备作业03 20162308马平川
查看>>
【Java】嵌套For循环性能优化案例
查看>>
面试了一个开发人员
查看>>
软件工程及软件项目开发流程
查看>>
关于android4.3 bluetooth4.0的那些事儿
查看>>
嵌入式成长轨迹14 【嵌入式环境及基础】【Linux下的C编程 上】【gcc、gdb和GNU Make】...
查看>>
C语言讲义——变量的输出
查看>>