[Floyd] Jzoj P1224 最小密度路径

Description

这次的任务很简单,给出了一张有N个点M条边的加权有向无环图,接下来有Q个询问,每个询问包括2个节点X和Y,要求算出从X到Y的一条路径,使得密度最小(密度的定义为,路径上边的权值和除以边的数量)。
 

Input

第一行包括2个整数N和M。
以下M行,每行三个数字A、B、W,表示从A到B有一条权值为W的有向边。
再下一行有一个整数Q。
以下Q行,每行一个询问X和Y,如题意所诉。

Output

对于每个询问输出一行,表示该询问的最小密度路径的密度(保留3位小数),如果不存在这么一条路径输出“OMG!”(不含引号)。
 

Sample Input

3 3
1 3 5
2 1 6
2 3 6
2
1 3
2 3

Sample Output

5.000
5.500
 

Data Constraint

 
 

Hint

【数据规模】
对于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。

 

题解

  • 设f[i][j][k]表示从i到j的路径走了k条边的最短路径,其实就是跟Floyd一样多了一维而已
  • 求答案就直接枚举就好了

代码

 1 #include<stdio.h>
 2 #define ll long long
 3 using namespace std;
 4 #define INF 1000000000
 5 int n,m,q;
 6 int dis[60][60][1010];
 7 int main()
 8 {
 9     scanf("%d%d",&n,&m);
10     for (int l=1;l<=m;l++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) dis[i][j][l]=INF;
11     for(int i=1;i<=m;i++)
12     {
13         ll a,b,w;
14         scanf("%lld%lld%lld",&a,&b,&w);
15         if(dis[a][b][1]>w) dis[a][b][1]=w;
16     }
17     for (int l=2;l<=m;l++)
18         for (int k=1;k<=n;k++)
19             for (int i=1;i<=n;i++)
20                 for (int j=1;j<=n;j++) if(dis[i][j][l]>dis[i][k][l-1]+dis[k][j][1]) dis[i][j][l]=dis[i][k][l-1]+dis[k][j][1];
21     scanf("%d",&q);
22     while (q--)
23     {
24         int x,y;
25         double ans=INF,min=INF;
26         scanf("%d%d",&x,&y);
27         for (int l=1;l<=n;l++)
28         {
29             if (dis[x][y][l]<INF) ans=double(dis[x][y][l])/double(l);
30             if (ans<min) min=ans;
31         }
32         if (min==INF) printf("OMG!\n"); else printf("%.3lf\n",min);
33     }
34 }

 

posted @ 2019-03-04 20:53  BEYang_Z  阅读(252)  评论(0编辑  收藏  举报