This filename has no special meanings (tfnhnsm)

来源:互联网 发布:手机变砖刷机软件 编辑:程序博客网 时间:2024/05/17 21:55
This filename has no special meanings
(tfnhnsm)
【问题描述】
现在,保密成为一个很重要也很困难的问题。如果没有做好,后果是严重的。
比如,有个人没有自己去修电脑,又没有拆硬盘,后来的事大家都知道了。
当然,对保密最需求的当然是军方,其次才是像那个人。为了应付现在天上
飞来飞去的卫星,军事基地一般都会建造在地下。
某K 国的军事基地是这样子的:地面上两排大天井共n1 个作为出入口,内
部是许多除可以共享出入口外互不连通的空腔,每个空腔有且只有两个出入口,
并且这两个出入口不会在同一排。为了方便起见,两排出入口分别编号为1,3,5…
和2,4,6…并且最大的编号为n1。
虽然上面扯了那么多关于保密的东西,但是其实解密也是一件很纠结的事

情。但其实最简单直接暴力无脑的解密方法就是找个人去看看。。。

我们有很牛X 的特种部队,只需要派出一支特种部队到K 国基地的某个出
入口,那么和这个出入口直接相连的所有空腔都可以被探索,但也只有这些空腔
可以被这支部队探索。现在有足够多的特种部队可以供你调遣,你必须使用他们

调查完所有的K 国基地内的空腔。
当然,你的基地离K 国基地不会太近,周边的地图将会给你,表示为n 个检
查点和m 条连接这些点的道路,其中点1 到点n1 就是K 国基地的出入口,点n
是你的部队的出发点。对每条道路,有不同的通行时间t 和安全系数s。因为情
报部门只对单向的道路安全系数进行了评估,所以这些道路只允许单向通行,并
且不会存在环。
一支特种部队从你的基地出发,通过某条路径,到达某个K 国基地出入口,
此时这支部队的危险性表示为总时间和这条路径经过的所有道路的安全系数和
的比值。整个行动的危险性表示为你派出的所有部队的危险性之和。你需要使这
个值最小的情况下探索整个K 国基地。

快点完成这个任务,在K 国的叫兽宣布你是K 国人之前。
【输入格式】
第一行2 个正整数n,m (4 <= n <= 700, m <= 100000) 表示整个地区地图上
的检查点和道路数。
下面m 行,每行4 个正整数a, b, t, s(a, b <=n, 1 <= t, s <= 10)表示一条从a 到
b 的道路需时为t,安全系数为s。
接下来1 行2 个正整数m1 和n1(m1 <= 40000, n1 < min{n, 161}), m1 表示K
国基地空腔的个数,n1 表示K 国基地出入口的个数。
再接下来m1 行,每行2 个正整数u, v (u, v<=n1, u 是奇数,v 是偶数),表示
每个空腔的2 个出入口。
【输出格式】
一行,最小的危险性,保留一位小数。或者输出”-1”(无引号)表示此任务
不可能完成。
【样例输入】

5 5
5 1 10 1
5 1 10 1
5 2 9 1
5 3 7 1
5 4 8 1
4 4
1 2
1 4
3 2
3 4
【样例输出】

17.0
【数据规模和约定】
对30%的数据,n<=30
对60%的数据,n<=300

另外40%的数据n1<=20


首先用分数规划求1..n1到达所需最小费用

然后就成为了一个求最小代价全覆盖的问题

问题就转换为了最大流问题


program tfnhnsm;const  eps=1e-5;var  u,v,tot,n,m,i,j,k,a,b,t,p,m1,n1:longint;  dl:array [0..50001] of longint;  dis,cost:array [0..701] of double;  root:array [0..701] of longint;  point,safe,time,next:array [0..100001] of longint;  all,max,ans,s,e,mid:double;  last:array [0..162] of longint;  yes:array [0..162] of boolean;  can:array [0..701] of boolean;  flow:array [0..162,0..162] of double;  dd:array [0..162,0..1001] of longint;function spfa (ans:double;now:longint):boolean;var  i,k,tot:longint;begin  for i:=1 to n do    dis[i]:=1e+20;  i:=1;  tot:=1;  dl[1]:=n;  dis[n]:=0;  while i<=tot do    begin      k:=root[dl[i]];      while k<>0 do        begin          if (dis[point[k]]>dis[dl[i]]+safe[k]-time[k]*ans) then            begin              dis[point[k]]:=dis[dl[i]]+safe[k]-time[k]*ans;              if (point[k]=now)and(dis[now]<eps) then exit(true);              inc(tot);              dl[tot]:=point[k];            end;          k:=next[k];        end;      inc(i);    end;  exit(dis[now]<eps);end;procedure search (now:longint);begin  s:=0;  e:=24;  while e-s>eps do    begin      mid:=(s+e)/2;      if spfa(mid,now) then e:=mid                       else s:=mid;    end;  cost[now]:=s;end;procedure connect (a,b,s,t:longint);begin  inc(tot);  point[tot]:=b;  safe[tot]:=s;  time[tot]:=t;  next[tot]:=root[a];  root[a]:=tot;end;procedure maxflow;begin  repeat    fillchar(yes,sizeof(yes),false);    tot:=1;    i:=1;    yes[0]:=true;    dl[1]:=0;    while i<=tot do      begin        if dl[i]=n1+1 then break;        for j:=1 to dd[dl[i],0] do          if (flow[dl[i],dd[dl[i],j]]>0)and(not yes[dd[dl[i],j]]) then            begin              yes[dd[dl[i],j]]:=true;              inc(tot);              dl[tot]:=dd[dl[i],j];              last[dl[tot]]:=dl[i];            end;        inc(i);      end;    if not yes[n1+1] then break;    i:=n1+1;    max:=9999999999;    while i<>0 do      begin        if flow[last[i],i]<max then max:=flow[last[i],i];        i:=last[i];      end;    ans:=ans+max;    i:=n1+1;    while i<>0 do      begin        flow[last[i],i]:=flow[last[i],i]-max;        flow[i,last[i]]:=flow[i,last[i]]+max;        i:=last[i];      end;  until false;end;procedure floodfill;begin  i:=1;  tot:=1;  dl[1]:=n;  can[n]:=true;  while i<=tot do    begin      k:=root[dl[i]];      while k<>0 do        begin          if not can[point[k]] then            begin              can[point[k]]:=true;              inc(tot);              dl[tot]:=point[k];            end;          k:=next[k];        end;      inc(i);    end;end;begin  assign(input,'tfnhnsm.in');  reset(input);  assign(output,'tfnhnsm.out');  rewrite(output);  read(n,m);  for i:=1 to m do    begin      read(a,b,t,p);      connect(a,b,t,p);    end;  read(m1,n1);  fillchar(can,sizeof(can),false);  floodfill;  all:=0;  for i:=1 to n1 do    if can[i] then      begin        search(i);        all:=all+cost[i];      end              else    cost[i]:=9999999;  for i:=1 to m1 do    begin      read(u,v);      if (not can[u])and(not can[v]) then        begin          writeln(-1);          close(input);          close(output);          halt;        end;      dd[u,0]:=dd[u,0]+1;      dd[u,dd[u,0]]:=v;      dd[v,0]:=dd[v,0]+1;      dd[v,dd[v,0]]:=u;      flow[u,v]:=999999999;    end;  for i:=1 to n1 do    if i and 1 = 1 then      begin        dd[0,0]:=dd[0,0]+1;        dd[0,dd[0,0]]:=i;        dd[i,0]:=dd[i,0]+1;        dd[i,dd[i,0]]:=0;        flow[0,i]:=cost[i];      end                   else      begin        dd[n1+1,0]:=dd[n1+1,0]+1;        dd[n1+1,dd[n1+1,0]]:=i;        dd[i,0]:=dd[i,0]+1;        dd[i,dd[i,0]]:=n1+1;        flow[i,n1+1]:=cost[i];      end;  ans:=0;  maxflow;  writeln(ans:0:1);  close(input);  close(output);end.




原创粉丝点击