您的位置:首页 > 其它

POJ3613 Cow Relays(矩阵快速幂)

2016-05-17 09:38 323 查看
题目大概要求从起点到终点恰好经过k条边的最短路。

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

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

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

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF (1<<29)

int N;

struct Mat{
int m[222][222];
Mat(){
for(int i=0; i<222; ++i){
for(int j=0; j<222; ++j) m[i][j]=INF;
}
}
};
Mat operator*(const Mat &m1,const Mat &m2){
Mat m;
for(int i=0; i<N; ++i){
for(int j=0; j<N; ++j){
for(int k=0; k<N; ++k){
m.m[i][j]=min(m.m[i][j],m1.m[i][k]+m2.m[k][j]);
}
}
}
return m;
};

int idx[1111];

int main(){
Mat m;
int n,t,s,e,a,b,c;
scanf("%d%d%d%d",&n,&t,&s,&e);
memset(idx,-1,sizeof(idx));
while(t--){
scanf("%d%d%d",&c,&a,&b);
if(idx[a]==-1){
idx[a]=N++;
}
if(idx[b]==-1){
idx[b]=N++;
}
m.m[idx[a]][idx[b]]=m.m[idx[b]][idx[a]]=c;
}
--n;
Mat ans=m;
while(n){
if(n&1){
ans=ans*m;
}
m=m*m;
n>>=1;
}
printf("%d",ans.m[idx[s]][idx[e]]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: