JZOJ_4735. 最小圈 (Standard IO)

Description

对于一张有向图,要你求图中最小圈的平均值最小是多少,即若一个圈经过k个节点,那么一个圈的平均值为圈上k条边权的和除以k,现要求其中的最小值

Input

第一行2个正整数,分别为n和m
   以下m行,每行3个数,表示边连接的信息

Output

一行一个数,表示最小圈的值。你的答案被视为正确当且仅当与标准答案的绝对误差不超过1e-5

Solution

新思想:分数规划,将求值问题变成可行性判断问题。

然后要利用深搜版的 SPFA或者dfs,用于判负环,来求可行性,如果是宽搜版的会被卡 TLE。

代码

 

 1 type
 2   arr=record
 3     y,next:longint;
 4     w:real;
 5   end;
 6 var
 7   bo:boolean;
 8   n,m,nm:longint;
 9   a:array [0..10001] of arr;
10   d:array [0..3001] of real;
11   ls,v:array [0..3001] of longint;
12 procedure add(x,y:longint;z:real);
13 begin
14   inc(nm);
15   a[nm].y:=y; a[nm].w:=z;
16   a[nm].next:=ls[x]; ls[x]:=nm;
17 end;
18 
19 procedure init;
20 var
21   i,x,y:longint;
22   z:real;
23 begin
24   readln(n,m);
25   nm:=0;
26   for i:=1 to m do
27     begin
28       readln(x,y,z);
29       add(x,y,z);
30     end;
31 end;
32 
33 procedure dfs(x:longint;mid:real);
34 var
35   i:longint;
36 begin
37   v[x]:=1; i:=ls[x];
38   while i<>0 do
39     with a[i] do
40       begin
41         if d[x]+w-mid<d[y] then
42           begin
43             if v[y]=1 then
44               begin
45                 bo:=true;
46                 exit;
47               end;
48             d[y]:=d[x]+w-mid;
49             dfs(y,mid);
50             if bo then exit;
51           end;
52         i:=next;
53       end;
54   v[x]:=0;
55 end;
56 
57 function pd(mid:real):boolean;
58 var
59   i:longint;
60 begin
61   for i:=1 to n do
62     begin
63       d[i]:=0; v[i]:=0;
64     end;
65   for i:=1 to n do
66     begin
67       bo:=false;
68       dfs(i,mid);
69       if bo then exit(true);
70     end;
71   exit(false);
72 end;
73 
74 procedure main;
75 var
76   l,r,mid:real;
77 begin
78   l:=-100000; r:=100000;
79   while r-l>=0.0000001 do
80     begin
81       mid:=(l+r)/2;
82       if pd(mid) then r:=mid
83                  else l:=mid;
84     end;
85   writeln(mid:0:6);
86 end;
87 
88 begin
89   init;
90   main;
91 end.

 

posted @ 2018-08-24 16:53  猪都哭了  阅读(122)  评论(0编辑  收藏  举报