POJ3613 Cow Relays(矩阵快速幂)

题目大概要求从起点到终点恰好经过k条边的最短路。

离散数学告诉我们邻接矩阵的k次幂就能得出恰好经过k条路的信息,比如POJ2778

这题也一样,矩阵的幂运算定义成min,而min满足结合律,所以可以用快速幂求解。

另外这题点的序号要离散化一下,最多也就200个点。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define INF (1<<29)
 6 
 7 int N;
 8 
 9 struct Mat{
10     int m[222][222];
11     Mat(){
12         for(int i=0; i<222; ++i){
13             for(int j=0; j<222; ++j) m[i][j]=INF;
14         }
15     }
16 };
17 Mat operator*(const Mat &m1,const Mat &m2){
18     Mat m;
19     for(int i=0; i<N; ++i){
20         for(int j=0; j<N; ++j){
21             for(int k=0; k<N; ++k){
22                 m.m[i][j]=min(m.m[i][j],m1.m[i][k]+m2.m[k][j]);
23             }
24         }
25     }
26     return m;
27 };
28 
29 int idx[1111];
30 
31 int main(){
32     Mat m;
33     int n,t,s,e,a,b,c;
34     scanf("%d%d%d%d",&n,&t,&s,&e);
35     memset(idx,-1,sizeof(idx));
36     while(t--){
37         scanf("%d%d%d",&c,&a,&b);
38         if(idx[a]==-1){
39             idx[a]=N++;
40         }
41         if(idx[b]==-1){
42             idx[b]=N++;
43         }
44         m.m[idx[a]][idx[b]]=m.m[idx[b]][idx[a]]=c;
45     }
46     --n;
47     Mat ans=m;
48     while(n){
49         if(n&1){
50             ans=ans*m;
51         }
52         m=m*m;
53         n>>=1;
54     }
55     printf("%d",ans.m[idx[s]][idx[e]]);
56     return 0;
57 }
原文地址:https://www.cnblogs.com/WABoss/p/5500353.html