POJ 3613
可以利用DP的思想来做,不过是在DP时加上了矩阵乘法的思想而已,但乘法不是真的乘法,而是mp[a][i]+mp[i][b]<mp[a][b]则更新,其实更像FLOYD。
但这是符合乘法的格式的。
我们可以利用快速幂的做法来降低复杂度,同时把那些点离散化一下,因为T才100,最多是200多个点而已。
仅有此还不够,我觉得这道题更重要的是一个初始化的问题。
这题的数据可能有回到原点的数据,那么,若I->I=0的话,则会一直不动,所以要初始化到I->I=INF;
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int inf=0x3f3f3f3f;
const int Maxn=220;
int mark[1010];
struct Matrax {
int m[Maxn][Maxn];
};
Matrax a;
int counted=0;
Matrax multi(Matrax a,Matrax b){
Matrax c;
for(int i=0;i<counted;i++){
for(int j=0;j<counted;j++){
c.m[i][j]=inf;
for(int k=0;k<counted;k++)
c.m[i][j]=min(c.m[i][j],a.m[i][k]+b.m[k][j]);
}
}
return c;
}
Matrax Powerg(int k){
bool flag=false;
Matrax ans,p=a;
while(k){
if(k&1){
if(!flag){
ans=p;
flag=true;
}
else {
ans=multi(ans,p);
}
}
k>>=1;
p=multi(p,p);
}
return ans;
}
int main(){
int n,t,s,e,l,u,v,uu,vv;
while(scanf("%d%d%d%d",&n,&t,&s,&e)!=EOF){
counted=0;
memset(mark,-1,sizeof(mark));
for(int i=0;i<Maxn;i++){
for(int j=0;j<Maxn;j++){
a.m[i][j]=inf;
}
}
for(int i=0;i<t;i++){
scanf("%d%d%d",&l,&uu,&vv);
if(mark[uu]==-1)
mark[uu]=counted++;
if(mark[vv]==-1)
mark[vv]=counted++;
u=mark[uu]; v=mark[vv];
a.m[u][v]=a.m[v][u]=l;
}
Matrax ans=Powerg(n);
s=mark[s]; e=mark[e];
printf("%d\n",ans.m[s][e]);
}
return 0;
}

浙公网安备 33010602011771号