Floyd算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在)
从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。
http://cogs.pro/cogs/problem/problem.php?pid=2
/**************************************************************************************************** 最短路 Floyd+输出路径 ********************************************************************************************************/ #include<iostream> #include<cmath> #include<algorithm> #include<cstdio> #include<string.h> using namespace std; int value[101][101],path[101][101],djs[101][101];//value为邻接矩阵,path为路径 bool a[101][101];//a[i][j]记录i到j是否可达 inline void pw(int n,int v){//输出路径 if(path[n][v]!=v)pw(path[n][v],v),pw(n,path[n][v]); else printf("%d ",v); return; } inline void pr(int n,int v){//输出函数 printf("%d: ",n); if(!a[n][v]){ printf("no ");return; } printf("path:"); pw(n,v);printf("%d cost:%d ",n,value[n][v]); } int main() { freopen("djs.in","r",stdin); freopen ("djs.out","w",stdout); int n,m,v,x,y,z; scanf("%d%d%d",&n,&m,&v); for(int i=1;i<=m;i++){//读入 scanf("%d%d%d",&y,&x,&z); value[x][y]=z;a[x][y]=1; path[x][y]=y;//初始路径为x直接到y } for(int k=0;k<n;k++){//Floyd算法主体 for(int j=0;j<n;j++){ for(int i=0;i<n;i++){ if(a[i][k]&&a[k][j]&&j!=i){ if(!a[i][j])value[i][j]=value[i][k]+value[k][j],a[i][j]=1,path[i][j]=k; else if(value[i][k]+value[k][j]<value[i][j])value[i][j]=value[i][k]+value[k][j],a[i][j]=1,path[i][j]=k; } } } } for(int i=0;i<n;i++){//输出 pr(i,v); } return 0; }