zoukankan      html  css  js  c++  java
  • bzoj 3275: Number (最小割)

    题目的意思是要选一些数,但是这些数如果满足两个条件的话就不能一起被选。

    type
      arr=record
        toward,next,cap:longint;
      end;
     
    const
      maxn=4000;
      maxm=300000;
    var
      gap,first,cur,d,num1,num2:array[0..maxn]of longint;
      edge:array[0..maxm]of arr;
      tot,s,t,n,esum,sum:longint;
     
     
    function min(x,y:longint):longint;
    begin
      if x<y then exit(x);
      exit(y);
    end;
     
    procedure add(j,k,l:longint);
    begin
      //writeln(j,' ',k,' ',l);
      inc(esum);
      edge[esum].toward:=k;
      edge[esum].next:=first[j];
      first[j]:=esum;
      edge[esum].cap:=l;
    end;
     
    procedure addedge(j,k,l:longint);
    begin
      add(j,k,l);
      add(k,j,0);
    end;
     
    function sap(x,flow:longint):longint;
    var
      i,too,more,now:longint;
    begin
      if x=t then exit(flow);
      now:=0;
      i:=cur[x];
      while i>=0 do begin
        too:=edge[i].toward;
        if (d[x]=d[too]+1) and (edge[i].cap>0) then begin
          more:=sap(too,min(edge[i].cap,flow-now));
          dec(edge[i].cap,more);
          inc(edge[i xor 1].cap,more);
          inc(now,more);
          cur[x]:=i;
          if flow=now then exit(flow);
        end;
        i:=edge[i].next;
      end;
      dec(gap[d[x]]);
      if gap[d[x]]=0 then d[s]:=tot;
      inc(d[x]);
      inc(gap[d[x]]);
      cur[x]:=first[x];
      exit(now);
    end;
     
    function maxflow:longint;
    var
      i,ans:longint;
    begin
      fillchar(d,sizeof(d),0);
      fillchar(gap,sizeof(gap),0);
      gap[0]:=tot;
      for i:=1 to tot do cur[i]:=first[i];
      ans:=0;
      while d[s]<tot do
        inc(ans,sap(s,maxlongint));
      exit(ans);
    end;
     
    function gcd(x,y:longint):boolean;
    begin
      if y=0 then exit(x=1);
      exit(gcd(y,x mod y));
    end;
     
    procedure into;
    var
      i,j,tot1,tot2,k:longint;
    begin
      readln(n);
      esum:=-1;
      fillchar(first,sizeof(first),255);
      tot1:=0;
      tot2:=0;
      for i:=1 to n do begin
        read(j);
        if j and 1=1 then begin
          inc(tot1);
          num1[tot1]:=j;
        end
        else begin
          inc(tot2);
          num2[tot2]:=j;
        end;
        inc(sum,j);
      end;
      for i:=1 to tot1 do
        for j:=1 to tot2 do
          if gcd(num1[i],num2[j]) then begin
            k:=sqr(num1[i])+sqr(num2[j]);
            if sqr(trunc(sqrt(k)))=k then addedge(i,j+tot1,maxlongint);
          end;
     // writeln;
      tot:=tot1+tot2+2;
      s:=tot-1;
      t:=tot;
      for i:=1 to tot1 do addedge(s,i,num1[i]);
      for i:=1 to tot2 do addedge(i+tot1,t,num2[i]);
     { for i:=1 to tot1 do writeln(i,' ',num1[i]);
      for i:=1 to tot2 do writeln(i,' ',num2[i]); }
    end;
     
    begin
      into;
      writeln(sum-maxflow);
      readln;
      readln;
    end.
    View Code
  • 相关阅读:
    165. Compare Version Numbers
    164. Maximum Gap
    3、桶排序
    162. Find Peak Element
    160. Intersection of Two Linked Lists
    155. Min Stack
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    Linux/Unix系统编程手册 第二章:基本概念
    Linux/Unix系统编程手册 第一章:历史和标准
  • 原文地址:https://www.cnblogs.com/Macaulish/p/4358137.html
Copyright © 2011-2022 走看看