传送门: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;
}