zoukankan      html  css  js  c++  java
  • 最小密度路径

    给一个有向图,顶点数少于50,有Q条询问(Q<=100000),对于每条询问(x1 y1),输出他们之间的最小密度路径的密度(长度比边数)

    两种实践方法,一个是FLOYD,再就是二维SPFA,注意数据有环,SPFA时要控制边数少于n才行,至于为什么,是困扰几代人的烦恼了。

    d[i,j,k]表示从i到j走过k条路径的最小路径长度

    floyd

    View Code
     1 program path(input,output);
    2 var
    3 i,j,k,l,m,n,w,p,x,y:longint;
    4 max,tmp:real;
    5 f:array[0..51,0..51,0..51] of longint;
    6 begin
    7 assign(input,'path.in');
    8 reset(input);
    9 assign(output,'path.out');
    10 rewrite(output);
    11 readln(n,m);
    12 fillchar(f,sizeof(f),255);
    13 for i:=1 to m do
    14 begin
    15 readln(x,y,w);
    16 if (f[x,y,1]=-1) or (f[x,y,1]>w) then
    17 f[x,y,1]:=w;
    18 end;
    19 for i:=1 to n do f[i,i,0]:=0;
    20 for l:=2 to n do
    21 for k:=1 to n do
    22 for i:=1 to n do
    23 for j:=1 to n do
    24 if (f[i,k,l-1]>-1) and (f[k,j,1]>-1) and
    25 ((f[i,j,l]=-1) or (f[i,k,l-1]+f[k,j,1]<f[i,j,l])) then
    26 f[i,j,l]:=f[i,k,l-1]+f[k,j,1];
    27 readln(p);
    28 for p:=1 to p do
    29 begin
    30 readln(x,y);
    31 max:=100110001;
    32 for i:=0 to n do
    33 if (f[x,y,i]<>-1) and (f[x,y,i]<max*i) then max:=f[x,y,i]/i;
    34 if max<>100110001 then writeln(max:0:3)
    35 else writeln('OMG!');
    36 end;
    37 close(input);
    38 close(output);
    39 end.

    SPFA

    View Code
      1 program path(input,output);
    2 type
    3 node = ^link;
    4 link = record
    5 goal,w : longint;
    6 next : node;
    7 end;
    8 node2 = record
    9 now : integer;
    10 step : longint;
    11 end;
    12 var
    13 l : array[0..100] of node;
    14 v : array[0..60,0..2010] of boolean;
    15 d : array[0..60,0..60,0..2010] of longint;
    16 g : array[0..60,0..60] of boolean;
    17 q : array[0..100010] of node2;
    18 answer : array[0..60,0..60] of double;
    19 n,m,qq : longint;
    20 procedure add(xx,yy,ww: longint );
    21 var
    22 tt : node;
    23 begin
    24 new(tt);
    25 tt^.w:=ww;
    26 tt^.goal:=yy;
    27 tt^.next:=l[xx];
    28 l[xx]:=tt;
    29 end; { add }
    30 procedure init;
    31 var
    32 i,j,k,xxx,yyy,www : longint;
    33 begin
    34 readln(n,m);
    35 for i:=1 to n do
    36 l[i]:=nil;
    37 for i:=1 to n do
    38 for j:=1 to n do
    39 for k:=1 to m do
    40 d[i,j,k]:=maxlongint>>2;
    41 for i:=1 to n do
    42 for j:=1 to n do
    43 if i=j then
    44 answer[i,j]:=0
    45 else
    46 answer[i,j]:=-1;
    47 fillchar(g,sizeof(g),false);
    48 for i:=1 to m do
    49 begin
    50 readln(xxx,yyy,www);
    51 add(xxx,yyy,www);
    52 g[xxx,yyy]:=true;
    53 end;
    54 for k:=1 to n do
    55 for i:=1 to n do
    56 for j:=1 to n do
    57 g[i,j]:=g[i,j] or (g[i,k] and g[k,j]);
    58 end; { init }
    59 procedure spfa(vo :longint );
    60 var
    61 head,tail : longint;
    62 t : node;
    63 begin
    64 fillchar(v,sizeof(v),false);
    65 head:=0;
    66 tail:=1;
    67 d[vo,vo,0]:=0;
    68 v[vo,0]:=true;
    69 q[1].step:=0;
    70 q[1].now:=vo;
    71 while head<tail do
    72 begin
    73 inc(head);
    74 v[q[head].now,q[head].step]:=false;
    75 if q[head].step=n then
    76 continue;
    77 t:=l[q[head].now];
    78 while t<>nil do
    79 begin
    80 if d[vo,q[head].now,q[head].step]+t^.w<d[vo,t^.goal,q[head].step+1] then
    81 begin
    82 d[vo,t^.goal,q[head].step+1]:=d[vo,q[head].now,q[head].step]+t^.w;
    83 if not v[t^.goal,q[head].step+1] then
    84 begin
    85 inc(tail);
    86 v[t^.goal,q[head].step+1]:=true;
    87 q[tail].now:=t^.goal;
    88 q[tail].step:=q[head].step+1;
    89 end;
    90 end;
    91 t:=t^.next;
    92 end;
    93 end;
    94 end; { spfa }
    95 procedure main;
    96 var
    97 i,j,x1,y1 : longint;
    98 begin
    99 for i:=1 to n do
    100 spfa(i);
    101 readln(qq);
    102 for i:=1 to qq do
    103 begin
    104 readln(x1,y1);
    105 if not g[x1,y1] then
    106 begin
    107 writeln('OMG!');
    108 continue;
    109 end;
    110 if answer[x1,y1]>=0 then
    111 begin
    112 writeln(answer[x1,y1]:0:3);
    113 continue;
    114 end;
    115 answer[x1,y1]:=999999999;
    116 for j:=1 to m do
    117 if d[x1,y1,j]<(maxlongint>>2) then
    118 if (d[x1,y1,j]/j)<answer[x1,y1] then
    119 answer[x1,y1]:=d[x1,y1,j]/j;
    120 writeln(answer[x1,y1]:0:3);
    121 end;
    122 end; { main }
    123 begin
    124 assign(input,'path.in');reset(input);
    125 assign(output,'path.out');rewrite(output);
    126 init;
    127 main;
    128 close(input);
    129 close(output);
    130 end.




  • 相关阅读:
    让网络编程更轻松和有趣 t-io
    设计一个百万级的消息推送系统
    前端安全系列之二:如何防止CSRF攻击
    Maven仓库下载jar包失败的处理方案
    SpringBoot2中配置文件的调整,升级SpringBoot2时候注意的坑
    Table折叠小技巧html-demo
    mysql如何分类统计数量
    前台登录和Token信息交互流程
    windows下安装mysql5.6
    【读书笔记】-- 你不知道的JavaScript
  • 原文地址:https://www.cnblogs.com/neverforget/p/2379280.html
Copyright © 2011-2022 走看看