zoukankan      html  css  js  c++  java
  • bzoj4514 [Sdoi2016]数字配对(网络流)

    Description

    有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。
    若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数,
    那么这两个数字可以配对,并获得 ci×cj 的价值。
    一个数字只能参与一次配对,可以不参与配对。
    在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。
     

    Input

    第一行一个整数 n。
    第二行 n 个整数 a1、a2、……、an。
    第三行 n 个整数 b1、b2、……、bn。
    第四行 n 个整数 c1、c2、……、cn。
     
     

    Output

     一行一个数,最多进行多少次配对

     

    Sample Input

    3
    2 4 8
    2 200 7
    -1 -2 1

    Sample Output

    4
     

    HINT

     n≤200,ai≤10^9,bi≤10^5,∣ci∣≤10^5

    Source

    鸣谢Menci上传

    主要是要注意到质因数有几个(2^2算两个),这样个数为奇数只能与个数为偶数配对,个数为偶数只能和个数为奇数配对,然后就是一个二分图,随便建一建图跑最大费用流就好。

     1 program rrr(input,output);
     2 const
     3   inf=123456789012345;
     4 type
     5   etype=record
     6      t,c,next,rev:longint;
     7      w:int64;
     8   end;
     9 var
    10   e:array[0..100000]of etype;
    11   num,a,d,q,fre,frv:array[0..220]of longint;
    12   s:array[0..100010]of boolean;
    13   p:array[0..100010]of longint;
    14   c,dis:array[0..220]of int64;
    15   inq:array[0..220]of boolean;
    16   n,m,i,j,x,b,cnt,h,t,ans:longint;
    17   w,f:int64;
    18 function min(a,b:int64):int64;
    19 begin
    20    if a<b then exit(a) else exit(b);
    21 end;
    22 procedure ins(x,y,c:longint;w:int64);
    23 begin
    24    inc(cnt);e[cnt].t:=y;e[cnt].c:=c;e[cnt].w:=w;e[cnt].next:=a[x];a[x]:=cnt;
    25 end;
    26 procedure add(x,y,c:longint;w:int64);
    27 begin
    28    ins(x,y,c,w);e[cnt].rev:=cnt+1;ins(y,x,0,-w);e[cnt].rev:=cnt-1;
    29 end;
    30 procedure spfa;
    31 begin
    32    for i:=1 to n do dis[i]:=-inf;dis[0]:=0;
    33    h:=0;t:=1;q[1]:=0;inq[0]:=true;
    34    while h<>t do
    35       begin
    36          inc(h);if h>210 then h:=1;
    37          i:=a[q[h]];
    38          while i<>0 do
    39             begin
    40                if (e[i].c>0) and (dis[q[h]]+e[i].w>dis[e[i].t]) then
    41                   begin
    42                      dis[e[i].t]:=dis[q[h]]+e[i].w;
    43                      fre[e[i].t]:=i;frv[e[i].t]:=q[h];
    44                      if not inq[e[i].t] then
    45                         begin
    46                            inc(t);if t>210 then t:=1;
    47                            q[t]:=e[i].t;inq[e[i].t]:=true;
    48                         end;
    49                   end;
    50                i:=e[i].next;
    51             end;
    52          inq[q[h]]:=false;
    53       end;
    54 end;
    55 begin
    56    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
    57    fillchar(s,sizeof(s),true);s[1]:=false;
    58    for i:=2 to 320 do if s[i] then
    59       begin
    60          j:=i+i;while j<=100000 do begin s[j]:=false;j:=j+i; end;
    61       end;
    62    m:=0;for i:=2 to 100000 do if s[i] then begin inc(m);p[m]:=i; end;
    63    readln(n);
    64    for i:=1 to n do read(num[i]);
    65    for i:=1 to n do
    66       begin
    67          x:=num[i];j:=1;d[i]:=0;
    68          while x>1 do begin while x mod p[j]=0 do begin inc(d[i]);x:=x div p[j]; end;inc(j);if j>m then break; end;
    69          if x>1 then inc(d[i]);
    70       end;
    71    fillchar(a,sizeof(a),0);cnt:=0;
    72    for i:=1 to n do begin read(b);if d[i] mod 2=0 then add(i,n+1,b,0) else add(0,i,b,0); end;
    73    for i:=1 to n do read(c[i]);
    74    for i:=1 to n do for j:=i+1 to n do
    75       if (abs(d[i]-d[j])=1) and ((num[i] mod num[j]=0) or (num[j] mod num[i]=0)) then
    76          begin
    77             if d[i] mod 2=0 then add(j,i,100000000,c[i]*c[j]) else add(i,j,100000000,c[i]*c[j]);
    78          end;
    79    ans:=0;inc(n);w:=0;
    80    while true do
    81       begin
    82          spfa;
    83          if dis[n]=-inf then break;
    84          i:=n;f:=100000000;
    85          while i<>0 do begin f:=min(f,e[fre[i]].c);i:=frv[i]; end;
    86          if w+f*dis[n]<0 then begin ans:=ans+w div (-dis[n]);break; end
    87          else begin ans:=ans+f;w:=w+f*dis[n]; end;
    88          i:=n;while i<>0 do begin dec(e[fre[i]].c,f);inc(e[e[fre[i]].rev].c,f);i:=frv[i]; end;
    89       end;
    90    write(ans);
    91    close(input);close(output);
    92 end.
  • 相关阅读:
    个人技术博客(α)
    git常用命令合集
    软件工程实践2017第二次结对作业
    软件工程实践2017第一次结对作业
    软件工程实践2017第二次作业
    软件工程实践2017第一次作业
    学习总结
    约瑟夫
    今天是星期几
    斐波那契数列取石子游戏
  • 原文地址:https://www.cnblogs.com/Currier/p/6705927.html
Copyright © 2011-2022 走看看