洛谷P1730 最小密度路径
题目分析:
这道题我们用floyd来做,不过在这里要多一维来记录状态。我们用f[L][i][j]表示从i到j走过了l条边数的路径长度。跟新的时候这样做:f[L][i][j]=min(f[l-1[i][k]+f[1][k][j],f[L][i][j])即可。直接贴代码吧!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,q,l,k,i,j,x,y,z;
long long f[1010][55][55];
inline long long read(){
long long x=0,w=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
return x*w;
}
int main(){
scanf("%d%d",&n,&m);
for(register int l=1;l<=m;++l)//(注意这里是m,之前自己习惯的打了n,找了很久。)
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)
f[l][i][j]=1e9;
for(register int i=1;i<=m;++i){
int x,y,z;
x=read(),y=read(),z=read();
if(z<f[1][x][y]) f[1][x][y]=z;
}
for(register int l=2;l<=m;++l)
for(register int k=1;k<=n;++k)
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)
f[l][i][j]=min(f[l-1][i][k]+f[1][k][j],f[l][i][j]);
q=read();
for(register int i=1;i<=q;++i){
int x=read(),y=read();long double ans=1e9;
for(register int l=1;l<=m;++l)//总共有m条边,一个一个去试一下,找出最小的
if(ans*l>f[l][x][y]&&f[l][x][y]<1e9) ans=(long double)f[l][x][y]/(long double)l;
if(ans==1e9)printf("OMG!\n");
else printf("%.3Lf\n",ans);
}
return 0;
}