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
  • 相关阅读:
    2016/3/10 Java 错题
    2016/3/9 Java 错题集
    Java Socket 编程实验总结
    CSU 1290
    CSU 1307
    CSU 1060
    Problem B SPOJ DCEPC11I
    activemq 学习系列(二) 常用配置
    activemq 学习系列(一) 详细入门使用
    MySql 用户创建与授权
  • 原文地址:https://www.cnblogs.com/Macaulish/p/4358137.html
Copyright © 2011-2022 走看看