题目描述
这次的任务很简单,给出了一张有N 个点
输入
第一行包括2 个整数
以下
再下一行有一个整数
以下Q 行,每行一个询问
输出
对于每个询问输出一行,表示该询问的最小密度路径的密度(保留
样例输入
3
1
2
1
2
样例输出
5.000
5.500
提示
对于60% 的数据,有1≤N≤10 ,1≤M≤100 ,1≤W≤1000 ,1≤Q≤1000 ;
对于100% 的数据,有1≤N≤50 ,1≤M≤1000 ,1≤W≤100000 ,1≤Q≤100000 。
题解
有一句经典的话:如果状态有后效性,就加一维使它没有后效性。
看到上面那句话应该就可以懂怎么做了……如果不懂,看下一句……
加一维表示经过的边数,跑最短路……
spfa ,floyd ,什么什么的随便乱跑跑就好
f[i][j][k] 表示从i 到
代码
#include<stdio.h>
#include<cstring>
#define N 55
#define For(i,a,b) for (int i=a;i<=b;i++)
int n,m,q,u,v,f[N][N][N],c[N][N],p;
inline void floyd()
{
For(i,1,n) f[i][i][0]=0;
For(s,1,n) For(k,1,n) For(i,1,n) For(j,1,n) if (f[i][j][s]>f[i][k][s-1]+c[k][j])
f[i][j][s]=f[i][k][s-1]+c[k][j];
}
int main()
{
scanf("%d%d",&n,&m);
memset(c,0x3f,sizeof(c));
memset(f,0x3f,sizeof(f));
int inf=c[0][0];
while (m--)
{
scanf("%d%d%d",&u,&v,&p);
if (p<c[u][v]) c[u][v]=p;
}
floyd();
scanf("%d",&q);
while (q--)
{
scanf("%d%d",&u,&v);
double ans=18915758;
bool flag=0;
For(i,0,n) if (f[u][v][i]<inf)
{
flag=1;
if (ans*i>f[u][v][i]) ans=(double)f[u][v][i]/i;
}
if (flag) printf("%.3lf\n",ans);
else puts("OMG!");
}
}
本文介绍了一个关于求解加权有向无环图中两点间最小密度路径的问题,并提供了解决方案。通过增加一个维度来表示经过的边数,利用floyd算法计算最短路径,最终得出每个询问的最小密度路径。
274

被折叠的 条评论
为什么被折叠?



