zoukankan      html  css  js  c++  java
  • bzoj1189

    初看这题好像跟我mincost第一题很像,多了点门其实最短路/bfs与处理一下就可以了

    但是门只能容纳一个人

    所以,也就是说,费用是变的,怎么做?

    仔细想想,费用流好像不能处理费用改变的

    扔掉费用流,首先决策具有单调性,二分!

    当我们确定了时间之后,我们怎么快速的判断可行呢?

    由于门每分钟只能容纳一个人,也就是说,在这分钟内这个门只能被一个人匹配

    不禁想到了最大流/二分图匹配,暴力将每个门拆成对应时间点

    每个人对应能走的门连边然后匈牙利即可

    到这问题好像解决了(实际上也解决了);

    但我写着写着发现一个问题

    一开始的预处理,似乎不能简单的求每点到每个门的最短距离

    因为看起来有的门能到,实际却到不了

    比如

    XXDDX

    XXX.X

    X...X

    X...X

    XXXXX

    比如(1,3)的门是根本走不到的,被另一个门挡住了

    而且这是会影响结果的(在一个门被堵住,肯定要分流去另一个门)

    但我也没管,后来发现数据里好像也没这种情况(……)

    就这样吧

    一般的,费用流的费用都是不变的吧,否则都应该转化为二分+最大流判定吧

    为了方便我写了二分图匹配快一些

      1 const dx:array[1..4] of integer=(0,0,-1,1);
      2       dy:array[1..4] of integer=(1,-1,0,0);
      3       inf=10000007;
      4 type node=record
      5        point,next:longint;
      6      end;
      7 
      8 var a,map,dis:array[0..1010,0..1010] of longint;
      9     q:array[0..2000010] of longint;
     10     cx,d,p,b:array[0..1010] of longint;    
     11     cy:array[0..1001000] of longint;     //注意二分图另一个点集规模
     12     edge:array[0..5000010] of node;
     13     v:array[0..1001010] of boolean;
     14     k,ans,len,pep,sum,x,y,l,r,mid,n,m,t,i,j:longint;
     15     ch:char;
     16 
     17 procedure add(x,y:longint);
     18   begin
     19     inc(len);
     20     edge[len].point:=y;
     21     edge[len].next:=p[x];
     22     p[x]:=len;
     23   end;
     24 
     25 procedure spfa(k:longint);
     26   var s,i,x,f,r:longint;
     27   begin
     28     f:=1;
     29     r:=1;
     30     for i:=1 to t do
     31       d[i]:=inf;
     32     s:=b[k];
     33     d[s]:=0;
     34     fillchar(v,sizeof(v),false);
     35     v[s]:=true;
     36     q[1]:=s;
     37     while f<=r do
     38     begin
     39       x:=q[f];
     40       v[x]:=false;
     41       for i:=1 to t do
     42         if map[x,i]>0 then
     43           if d[i]>d[x]+map[x,i] then
     44           begin
     45             d[i]:=d[x]+map[x,i];
     46             if not v[i] then
     47             begin
     48               inc(r);
     49               q[r]:=i;
     50               v[i]:=true;
     51             end;
     52           end;
     53       inc(f);
     54     end;
     55     for i:=1 to pep do
     56       dis[i,k]:=d[i];
     57   end;
     58 
     59 function dfs(x:longint):boolean;
     60   var i,j:longint;
     61   begin
     62     i:=p[x];
     63     while i<>-1 do
     64     begin
     65       j:=edge[i].point;
     66       if not v[j] then
     67       begin
     68         v[j]:=true;
     69         if (cy[j]=-1) or dfs(cy[j]) then
     70         begin
     71           cy[j]:=x;
     72           cx[x]:=j;
     73           exit(true);
     74         end;
     75       end;
     76       i:=edge[i].next;
     77     end;
     78     exit(false);
     79   end;
     80 
     81 function check(k:longint):boolean;
     82   var s,i,j,w,z:longint;
     83   begin
     84     len:=0;
     85     fillchar(p,sizeof(p),255);
     86     for i:=1 to pep do
     87     begin
     88       for j:=1 to sum do
     89         if dis[i,j]<=k then
     90         begin
     91           for w:=0 to k-dis[i,j] do
     92           begin
     93             z:=(j-1)*k+dis[i,j]+w;        //暴力拆点
     94             add(i,z);
     95           end;
     96         end;
     97     end;
     98     fillchar(cx,sizeof(cx),255);
     99     fillchar(cy,sizeof(cy),255);
    100     for i:=1 to pep do
    101     begin
    102       fillchar(v,sizeof(v),false);
    103       if not dfs(i) then exit(false);     //匹配
    104     end;
    105     exit(true);
    106   end;
    107 
    108 begin
    109   readln(n,m);
    110   fillchar(a,sizeof(a),0);
    111   for i:=1 to n do
    112   begin
    113     for j:=1 to m do
    114     begin
    115       read(ch);
    116       if ch='.' then
    117       begin
    118         inc(pep);
    119         a[i,j]:=pep;
    120       end
    121       else if ch='D' then
    122       begin
    123         inc(sum);
    124         a[i,j]:=-sum;
    125       end;
    126     end;
    127     readln;
    128   end;
    129   sum:=0;
    130   for i:=1 to n do
    131     for j:=1 to m do
    132       if a[i,j]<0 then
    133       begin
    134         inc(sum);
    135         a[i,j]:=abs(a[i,j])+pep;
    136         b[sum]:=a[i,j];
    137       end;
    138 
    139   for i:=1 to n do                  //其实是有问题的预处理
    140     for j:=1 to m do
    141       if a[i,j]>0 then
    142       begin
    143         for k:=1 to 4 do
    144         begin
    145           x:=i+dx[k];
    146           y:=j+dy[k];
    147           if a[x,y]>0 then
    148           begin
    149             map[a[i,j],a[x,y]]:=1;
    150             map[a[i,j],a[x,y]]:=1;
    151           end;
    152         end;
    153       end;
    154   t:=pep+sum;
    155 
    156   for i:=1 to sum do
    157     spfa(i);                   
    158   l:=1;
    159   r:=1000;
    160   ans:=0;
    161   while l<=r do
    162   begin
    163     mid:=(l+r) shr 1;
    164     if check(mid) then
    165     begin
    166       ans:=mid;
    167       r:=mid-1;
    168     end
    169     else l:=mid+1;
    170   end;
    171   if ans=0 then writeln('impossible')
    172   else writeln(ans);
    173 end.
    View Code
  • 相关阅读:
    解释机器学习模型的一些方法(一)——数据可视化
    机器学习模型解释工具-Lime
    Hive SQL 语法学习与实践
    LeetCode 198. 打家劫舍(House Robber)LeetCode 213. 打家劫舍 II(House Robber II)
    LeetCode 148. 排序链表(Sort List)
    LeetCode 18. 四数之和(4Sum)
    LeetCode 12. 整数转罗马数字(Integer to Roman)
    LeetCode 31. 下一个排列(Next Permutation)
    LeetCode 168. Excel表列名称(Excel Sheet Column Title)
    论FPGA建模,与面向对象编程的相似性
  • 原文地址:https://www.cnblogs.com/phile/p/4473255.html
Copyright © 2011-2022 走看看