题解 POJ3613 【Cow Relays】
题目链接:Link
Problem
Solution
不难发现:Floyd的计算过程非常类似于矩阵乘法,尝试对其进行分治后不难证明可以套用矩阵快速幂的方法进行快速计算。
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cassert>
using namespace std;
const int oo=0x3f3f3f3f;
const int maxn=210;
int P,n,m,s,e,a[maxn],b[maxn],c[maxn],d[maxn][maxn],res[maxn][maxn],tmp[maxn][maxn];
map<int,int> hsh;
inline void cal(int a[maxn][maxn],int b[maxn][maxn],int c[maxn][maxn])
{
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
{
c[i][j]=oo;
for(int k=1;k<=n;k++) c[i][j]=min(c[i][j],a[i][k]+b[k][j]);
}
}
void ksm(int a[maxn][maxn],int b,int c[maxn][maxn])
{
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) c[i][j]=oo;
for(int i=1;i<=n;i++) c[i][i]=0;
for(;b;b>>=1)
{
if(b&1) { cal(a,c,tmp); memcpy(c,tmp,4*maxn*maxn); }
cal(a,a,tmp);
memcpy(a,tmp,4*maxn*maxn);
}
}
int main()
{
#ifdef local
freopen("pro.in","r",stdin);
#endif
scanf("%d%d%d%d",&P,&m,&s,&e);
for(int i=1;i<=m;i++) scanf("%d%d%d",&c[i],&a[i],&b[i]);
for(int i=1;i<=m;i++)
{
if(hsh[a[i]]==0) hsh[a[i]]=++n;
if(hsh[b[i]]==0) hsh[b[i]]=++n;
}
if(hsh[s]==0||hsh[e]==0) return 1;
memset(d,0x3f,sizeof(d));
// printf("n=%d s=%d e=%d\n",n,hsh[s],hsh[e]);
for(int i=1;i<=m;i++)
{
d[hsh[a[i]]][hsh[b[i]]]=d[hsh[b[i]]][hsh[a[i]]]=c[i];
// printf("(%d,%d,%d)\n",hsh[a[i]],hsh[b[i]],c[i]);
}
ksm(d,P,res);
printf("%d\n",res[hsh[s]][hsh[e]]);
return 0;
}
本作品由happyZYM采用知识共享 署名-非商业性使用-相同方式共享 4.0 (CC BY-NC-SA 4.0) 国际许可协议(镜像(简单版)镜像(完整版))进行许可。
转载请注明出处:https://www.cnblogs.com/happyZYM/p/11656662.html (近乎)全文转载而非引用的请在文首添加出处链接。