【改进floyed】最小密度路径(path)

 

最小密度路径(path)

【题目描述】

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

【输入格式】

 

第一行包括2个整数N和M。

    以下M行,每行三个数字A、B、W,表示从A到B有一条权值为W的有向边

    再下一行有一个整数Q。

    以下Q行,每行一个询问X和Y,如题意所诉。

【输出格式】

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

【输入样例】

3 3

1 3 5

2 1 6

2 3 6

2

1 3

2 3

【输出样例】

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。

===========================================

改进floyed

==========================

var
  n,m:longint;
  map:array[1..50,1..50]of longint;
  f:array[1..50,1..50,1..50]of longint;
  ans:array[1..50,1..50]of extended;
procedure init;
begin
  assign(input,'path.in');
  assign(output,'path.out');
  reset(input); rewrite(output);
end;

procedure terminate;
begin
  close(input); close(output);
  halt;
end;

procedure main;
var
  a,b,w:longint;
  l,i,j,k:longint;
  q:longint;
begin
  readln(n,m);
  fillchar(map,sizeof(map),$7);
  fillchar(f,sizeof(f),$7);
  for i:=1 to m do
    begin
      readln(a,b,w);
      if w<map[a,b] then map[a,b]:=w;
      f[1,a,b]:=map[a,b];
    end;
  for l:=2 to n do
  for k:=1 to n do
    for i:=1 to n do
      for j:=1 to n do
        if f[l,i,j]>f[l-1,i,k]+map[k,j] then f[l,i,j]:=f[l-1,i,k]+map[k,j];
  for i:=1 to n do
    for j:=1 to n do
      ans[i,j]:=maxlongint;
  for i:=1 to n do
    for j:=1 to n do
      for k:=1 to n do
        if f[i,j,k]/i<ans[j,k] then ans[j,k]:=f[i,j,k]/i;
  readln(q);
  for i:=1 to q do
    begin
      read(a,b);
      if ans[a,b]<100000 then writeln(ans[a,b]:0:3)
                         else writeln('OMG!');
    end;
end;

begin
  init;
  main;
  terminate;
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Floyd算法(也称为Floyd-Warshall算法)是一种用于寻找加权图中最短路径的算法。它可以用来解决带有负权边的图的最短路径问题。在C语言中,实现Floyd算法需要以下步骤: 1. 定义一个二维数组来存储图的邻接矩阵。 2. 初始化邻接矩阵,将不存在的边的距离设置为无穷大,将存在的边的距离设置为它们的权值。 3. 进行三重循环,其中第一重循环控制中间节点,第二重循环控制起点,第三重循环控制终点。在循环过程中,计算每对节点之间的最短路径,并更新邻接矩阵中的距离。 4. 最后,输出邻接矩阵中的最短路径矩阵即可。 具体实现可以参考以下示例代码: ```c #include <stdio.h> #define MAX 1000000 //定义一个无穷大的距离 int main() { int n, m; //n表示点的个数,m表示边的个数 scanf("%d %d", &n, &m); int graph[n][n]; //定义邻接矩阵 int i, j, k; //初始化邻接矩阵 for(i=0; i<n; i++) { for(j=0; j<n; j++) { graph[i][j] = (i == j) ? 0 : MAX; } } //读入边的信息,并更新邻接矩阵 int u, v, w; for(i=0; i<m; i++) { scanf("%d %d %d", &u, &v, &w); graph[u][v] = w; } //Floyd算法核心代码 for(k=0; k<n; k++) { for(i=0; i<n; i++) { for(j=0; j<n; j++) { if(graph[i][k] + graph[k][j] < graph[i][j]) { graph[i][j] = graph[i][k] + graph[k][j]; } } } } //输出最短路径矩阵 for(i=0; i<n; i++) { for(j=0; j<n; j++) { if(graph[i][j] == MAX) { printf("INF "); } else { printf("%d ", graph[i][j]); } } printf("\n"); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值