zoukankan      html  css  js  c++  java
  • bzoj1305

    让我们继续来练网络流;

    很明显是一个最大流的问题;

    二分枚举最多次数m,然后最大流判定;

    具体就是男生女生都拆成两个点i1,i2,之间连一条流量为k的边(男生i1-->i2,女生i2-->i1);

    i2连不喜欢的人,i1连喜欢的人

    最后,男生i1连源点流量为m,女生i1连汇点流量为m

    最后判断最大流是否等于n*m即可

    但做着做着,我发现好像好像二分+最大流不是很优,因为进行了很多重复操作

    但我也没管,先A了再说;

    后来看status发现很多人代码很短,用时0ms(我的最大流180ms)

    肯定有更简单的方法:

    贪心!……其实是错的……

      1 code(using maxflow):
      2 type node=record
      3        next,point,flow:longint;
      4      end;
      5 
      6 var edge:array[0..200010] of node;
      7     a:array[0..60,0..60] of boolean;
      8     cur,pre,p,numh,h:array[0..400] of longint;
      9     j,m,n,k,i,len,t,ans,l,r:longint;
     10     c:string;
     11 
     12 function min(a,b:longint):longint;
     13   begin
     14     if a>b then exit(b) else exit(a);
     15   end;
     16 
     17 procedure add(x,y,f:longint);
     18   begin
     19     inc(len);
     20     edge[len].flow:=f;
     21     edge[len].point:=y;
     22     edge[len].next:=p[x];
     23     p[x]:=len;
     24   end;
     25 
     26 function sap(m:longint):boolean;
     27   var s,u,tmp,i,j,q:longint;
     28   begin
     29     len:=-1;
     30     fillchar(p,sizeof(p),255);
     31     for i:=1 to n do
     32     begin
     33       add(0,i,m);
     34       add(i,0,m);
     35       add(i+2*n,t,m);
     36       add(t,i+2*n,0);
     37       add(i,i+n,k);
     38       add(i+n,i,0);
     39       add(i+3*n,i+2*n,k);
     40       add(i+2*n,i+3*n,0);
     41     end;
     42     for i:=1 to n do
     43       for j:=1 to n do
     44         if a[i,j] then
     45         begin
     46           add(i,j+2*n,1);
     47           add(j+2*n,i,0);
     48         end
     49         else begin
     50           add(i+n,j+3*n,1);
     51           add(j+3*n,i+n,0);
     52         end;
     53     fillchar(numh,sizeof(numh),0);
     54     fillchar(h,sizeof(h),0);
     55     numh[0]:=t+1;
     56     u:=0;
     57     s:=0;
     58     while h[0]<t+1 do
     59     begin
     60       if u=t then
     61       begin
     62         i:=0;
     63         while i<>t do
     64         begin
     65           j:=cur[i];
     66           dec(edge[j].flow);
     67           inc(edge[j xor 1].flow);
     68           i:=edge[j].point;
     69         end;
     70         u:=0;
     71         inc(s);
     72         if s=n*m then exit(true);
     73       end;
     74       q:=-1;
     75       i:=p[u];
     76       while i<>-1 do
     77       begin
     78         j:=edge[i].point;
     79         if (edge[i].flow>0) and (h[u]=h[j]+1) then
     80         begin
     81           q:=i;
     82           break;
     83         end;
     84         i:=edge[i].next;
     85       end;
     86       if q<>-1 then
     87       begin
     88         cur[u]:=q;
     89         pre[j]:=u;
     90         u:=j;
     91       end
     92       else begin
     93         dec(numh[h[u]]);
     94         if numh[h[u]]=0 then exit(false);
     95         tmp:=t+1;
     96         i:=p[u];
     97         while i<>-1 do
     98         begin
     99           j:=edge[i].point;
    100           if edge[i].flow>0 then tmp:=min(tmp,h[j]);
    101           i:=edge[i].next;
    102         end;
    103         h[u]:=tmp+1;
    104         inc(numh[h[u]]);
    105         if u<>0 then u:=pre[u];
    106       end;
    107     end;
    108     exit(false);
    109   end;
    110 
    111 begin
    112   readln(n,k);
    113   for i:=1 to n do
    114   begin
    115     readln(c);
    116     for j:=1 to n do
    117     begin
    118       if c[j]='Y' then a[i,j]:=true
    119       else a[i,j]:=false;
    120     end;
    121   end;
    122   t:=n*4+1;
    123   l:=1;
    124   r:=n;
    125   ans:=0;
    126   while l<=r do
    127   begin
    128     m:=(l+r) shr 1;
    129     if sap(m) then
    130     begin
    131       ans:=m;
    132       l:=m+1;
    133     end
    134     else r:=m-1;
    135   end;
    136   writeln(ans);
    137 end.
    View Code
  • 相关阅读:
    GitLab 介绍
    git 标签
    git 分支
    git 仓库 撤销提交 git reset and 查看本地历史操作 git reflog
    git 仓库 回退功能 git checkout
    python 并发编程 多进程 练习题
    git 命令 查看历史提交 git log
    git 命令 git diff 查看 Git 区域文件的具体改动
    POJ 2608
    POJ 2610
  • 原文地址:https://www.cnblogs.com/phile/p/4473244.html
Copyright © 2011-2022 走看看