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; }