zoukankan      html  css  js  c++  java
  • bzoj1934 bzoj2768

    最小割的经典模型,体现出最小割的基本定义,把两个集合划分的最小代价

    把一开始同意的人连源点,不同意的连汇点,有关系的人之间连边,流量都为1

    不难发现,割两点(人)间的边就相当于朋友之间发生冲突

    割到连源汇点的边就相当于与原来意愿不同

    所以解决问题的方案等于图中的一个割

    则最少冲突数=最小割=最大流

      1 type node=record
      2        point,flow,next:longint;
      3      end;
      4 var edge:array[0..400010] of node;
      5     cur,p,pre,numh,h:array[0..2010] of longint;
      6     ans,len,i,j,x,y,n,m:longint;
      7 
      8 procedure add(x,y,f:longint);
      9   begin
     10     inc(len);
     11     edge[len].point:=y;
     12     edge[len].flow:=f;
     13     edge[len].next:=p[x];
     14     p[x]:=len;
     15   end;
     16 
     17 procedure sap;
     18   var tmp,u,i,j,neck,f,q:longint;
     19   begin
     20     u:=0;
     21     numh[0]:=n+1;
     22     fillchar(pre,sizeof(pre),255);
     23     fillchar(cur,sizeof(cur),255);
     24     while h[0]<n+1 do
     25     begin
     26       if u=n then
     27       begin
     28         i:=0;
     29         while i<>n do
     30         begin
     31           j:=cur[i];
     32           dec(edge[j].flow);
     33           inc(edge[j xor 1].flow);
     34           i:=edge[j].point;
     35         end;
     36         inc(ans);
     37         u:=0;
     38       end;
     39       q:=-1;
     40       i:=p[u];
     41       while i<>-1 do
     42       begin
     43         j:=edge[i].point;
     44         if (edge[i].flow>0) and (h[u]=h[j]+1) then
     45         begin
     46           q:=i;
     47           break;
     48         end;
     49         i:=edge[i].next;
     50       end;
     51       if q<>-1 then
     52       begin
     53         cur[u]:=q;
     54         pre[j]:=u;
     55         u:=j;
     56       end
     57       else begin
     58         dec(numh[h[u]]);
     59         if numh[h[u]]=0 then break;
     60         i:=p[u];
     61         tmp:=n+1;
     62         while i<>-1 do
     63         begin
     64           j:=edge[i].point;
     65           if (edge[i].flow>0) then tmp:=min(tmp,h[j]);
     66           i:=edge[i].next;
     67         end;
     68         h[u]:=tmp+1;
     69         inc(numh[h[u]]);
     70         if u<>0 then u:=pre[u];
     71       end;
     72     end;
     73   end;
     74 
     75 begin
     76   readln(n,m);
     77   len:=-1;
     78   fillchar(p,sizeof(p),255);
     79   for i:=1 to n do
     80   begin
     81     read(x);
     82     if x=0 then
     83     begin
     84       add(0,i,1);
     85       add(i,0,0);
     86     end
     87     else begin
     88       add(i,n+1,1);
     89       add(n+1,i,0);
     90     end;
     91   end;
     92   for i:=1 to m do
     93   begin
     94     readln(x,y);
     95     add(x,y,1);
     96     add(y,x,0);
     97     add(y,x,1);
     98     add(x,y,0);
     99   end;
    100   inc(n);
    101   sap;
    102   writeln(ans);
    103 end.
    View Code
  • 相关阅读:
    LeetCode "Jump Game"
    LeetCode "Pow(x,n)"
    LeetCode "Reverse Linked List II"
    LeetCode "Unique Binary Search Trees II"
    LeetCode "Combination Sum II"
    LeetCode "Divide Two Integers"
    LeetCode "First Missing Positive"
    LeetCode "Clone Graph"
    LeetCode "Decode Ways"
    LeetCode "Combinations"
  • 原文地址:https://www.cnblogs.com/phile/p/4473256.html
Copyright © 2011-2022 走看看