3 1 0.5 0.5 0.5 1 0.4 0.5 0.4 1 3 1 2 2 3 1 3
0.500 0.400 0.500
看到有求任意两点间的距离,认为Dijkstra算法会超时,想到用floyd算法,但是还没有看具体实现,便接着去学习,苦于强迫症,先看了Bellman-ford算法,听到同学说能用Dijkstra算法,便立刻回来写了,1次AC的感觉真爽
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const double EPS=0.0000000000001;//由于是乘法,而且权值小于等于1,怕产生精度问题,所以EPS定的很小 int n,m,s,e; double w[1005][1005],dis[1005][1005]; bool vis[1005],cal[1005][1005];//vis[i]表示某次Dijkstra时i节点是否已经为最优 //cal[i][j]表示前面的计算过程中是否已经计算出i与j之间的最短路 void Dijkstra() { int i,j,u; double tmp; for(i=1;i<=n;++i) { tmp=0; for(j=1;j<=n;++j) if(!vis[j]&&tmp+EPS<dis[s][j]) tmp=dis[s][u=j]; if(-EPS<tmp&&tmp<EPS) return ; vis[u]=cal[s][u]=cal[u][s]=true; for(j=1;j<=n;++j) if(!vis[j]&&(tmp=dis[s][u]*w[u][j])-EPS>dis[s][j]) dis[s][j]=dis[j][s]=tmp; } } int main() { int i,j,q; while(1==scanf("%d",&n)) { for(i=1;i<=n;++i) { for(j=1;j<=n;++j) { scanf("%lf",&w[i][j]); dis[i][j]=0; cal[i][j]=false; } dis[i][i]=1; cal[i][i]=true; } scanf("%d",&q); while(q--) { memset(vis,false,sizeof(vis)); scanf("%d%d",&s,&e); if(!cal[s][e]) Dijkstra(); if(-EPS<dis[s][e]&&dis[s][e]<EPS) printf("What a pity!\n"); else printf("%.3lf\n",dis[s][e]); } } return 0; }