【POJ】3613Cow Relays 倍增floyd&矩乘

传送门:poj3613


题解

f l o y d floyd floyd实际上就是 D P DP DP的过程:原矩阵表示只经过一条边的最短路,每当做一次矩阵处理: a [ i ] [ j ] = m i n ( a [ i ] [ k ] + a [ k ] [ j ] ) a[i][j]=min(a[i][k]+a[k][j]) a[i][j]=min(a[i][k]+a[k][j])时,相当于强制求经过2倍边数的最短路。所以将原数组做快速幂就得到了答案。
复杂度 O ( T 3 log ⁡ n ) O(T^3\log n) O(T3logn)


代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define RI register
using namespace std;
const int N=220,inf=1e9;

int n,m,mx,S,T,A[2][N][N],B[2][N][N];
int tot,exi[1010];

int main(){
	RI int i,j,k,x,y,z,pr=0,qr=0,mn,num;
	memset(B[0],0x3f,sizeof(B[0]));
	scanf("%d%d%d%d",&n,&m,&S,&T);
	for(i=1;i<=m;++i){
		scanf("%d%d%d",&z,&x,&y);
		if(!exi[x]) exi[x]=++tot;
		if(!exi[y]) exi[y]=++tot;
		x=exi[x];y=exi[y];
		B[0][x][y]=B[0][y][x]=z;
	}
	tot++;
	memcpy(A[0],B[0],sizeof(A[0]));
	for(--n;n;n>>=1){
	   if(n&1){
	      qr^=1;
	      for(i=1;i<tot;++i)
	       for(j=1;j<tot;++j){
	       	 for(mn=inf,k=1;k<tot;++k)
	       	  mn=min(mn,A[qr^1][i][k]+B[pr][k][j]);
	       	 A[qr][i][j]=mn;
	       }
	   }	
	   pr^=1;
	   for(i=1;i<tot;++i)
	    for(j=1;j<tot;++j){
			for(mn=inf,k=1;k<tot;++k)
			 mn=min(mn,B[pr^1][i][k]+B[pr^1][k][j]);
			B[pr][i][j]=mn;
	    }
	}
	printf("%d\n",A[qr][exi[S]][exi[T]]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值