题意:

有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。

若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数,

那么这两个数字可以配对,并获得 ci×cj 的价值。

一个数字只能参与一次配对,可以不参与配对。

在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。

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

思路:裸的费用流,LYY一年前就已AC

加边的时候INT64没用,WA了好久……

费用流中每次找出的最长(短)路显然是依次不增(减)的,所以当找到一次不足以增广所有边时计算最多能增加的流量,且终止

 const oo=<<;
var head,vet,next,q,a,b,c,flag,prime,fan,f:array[..]of longint;
pre:array[..,..]of longint;
inq:array[..]of boolean;
dis,len1,len2:array[..]of int64;
n,m,i,tot,j,x,source,src,s,t:longint;
ans,flow,flow1:int64;
p:boolean; function min(x,y:int64):int64;
begin
if x<y then exit(x);
exit(y);
end; function max(x,y:int64):int64;
begin
if x>y then exit(x);
exit(y);
end; procedure add(a,b:longint;c,d:int64);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len1[tot]:=c;
len2[tot]:=d;
head[a]:=tot; inc(tot);
next[tot]:=head[b];
vet[tot]:=a;
len1[tot]:=;
len2[tot]:=-d;
head[b]:=tot;
end; function spfa:boolean;
var u,e,v,i,t,w,t1,w1:longint;
begin
for i:= to s do
begin
dis[i]:=-oo;
inq[i]:=false;
end;
t:=; t1:=; w:=; w1:=; dis[source]:=; q[]:=source; inq[source]:=true;
while t<w do
begin
inc(t); inc(t1);
if t1= then t1:=;
u:=q[t1]; inq[u]:=false;
e:=head[u];
while e<> do
begin
v:=vet[e];
if (len1[e]>)and(dis[u]+len2[e]>dis[v]) then
begin
pre[v,]:=u; pre[v,]:=e;
dis[v]:=dis[u]+len2[e];
if not inq[v] then
begin
inc(w); inc(w1);
if w1= then w1:=;
q[w1]:=v; inq[v]:=true;
end;
end;
e:=next[e];
end;
end;
if dis[src]=-oo then exit(false);
exit(true);
end; procedure mcf;
var k,e:longint;
t,s,now,i:int64;
begin
t:=oo; k:=src; s:=;
while k<>source do
begin
e:=pre[k,];
t:=min(t,len1[e]);
s:=s+len2[e];
k:=pre[k,];
end; if ans+t*s< then
begin
p:=false;
t:=ans div (-s);
end;
k:=src;
while k<>source do
begin
e:=pre[k,];
len1[e]:=len1[e]-t;
len1[fan[e]]:=len1[fan[e]]+t;
k:=pre[k,];
end;
ans:=ans+t*s;
flow:=flow+t; end; begin
assign(input,'bzoj4514.in'); reset(input);
assign(output,'bzoj4514.out'); rewrite(output);
readln(n);
for i:= to do
if i and = then fan[i]:=i+
else fan[i]:=i-;
for i:= to n do read(a[i]);
for i:= to n do read(b[i]);
for i:= to n do read(c[i]);
for i:= to do
begin
if flag[i]= then
begin
inc(m); prime[m]:=i;
end;
j:=;
while (j<=m)and(prime[j]*i<=) do
begin
t:=prime[j]*i; flag[t]:=;
if i mod prime[j]= then break;
inc(j);
end;
end;
for i:= to n do
begin
x:=a[i]; f[i]:=;
j:=;
while (x>)and(j<=m) do
begin
while x mod prime[j]= do
begin
inc(f[i]);
x:=x div prime[j];
end;
inc(j);
end;
if x> then f[i]:=;
end;
source:=n+; src:=n+; s:=n+;
for i:= to n do
if f[i] and = then add(source,i,b[i],)
else add(i,src,b[i],);
for i:= to n do
for j:= to n do
if (f[i]=f[j]+)and(a[i] mod a[j]=) then
begin
if f[i] and = then add(i,j,maxlongint,int64(c[i])*c[j])
else add(j,i,maxlongint,int64(c[i])*c[j]);
end;
ans:=; flow:=; p:=true;
while spfa and p do mcf;
writeln(flow);
close(input);
close(output);
end.

【BZOJ4514】数字配对(费用流)的更多相关文章

  1. [bzoj4514]数字配对[费用流]

    今年SDOI的题,看到他们在做,看到过了一百多个人,然后就被虐惨啦... 果然考试的时候还是打不了高端算法,调了...几天 默默地yy了一个费用流构图: 源连所有点,配对的点连啊,所有点连汇... 后 ...

  2. [SDOI2016][bzoj4514] 数字配对 [费用流]

    题面 传送门 思路 一个数字能且只能匹配一次 这引导我们思考:一次代表什么?代表用到一定上限(b数组)就不能再用,同时每用一次会产生价值(c数组) 上限?价值?网络流! 把一次匹配设为一点流量,那产生 ...

  3. 【BZOJ4514】[Sdoi2016]数字配对 费用流

    [BZOJ4514][Sdoi2016]数字配对 Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ...

  4. 【BZOJ4514】【SDOI2016】数字配对 [费用流]

    数字配对 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 有 n 种数字,第 i 种数字是 ...

  5. bzoj4514: [Sdoi2016]数字配对--费用流

    看了一眼题目&数据范围,觉得应该是带下界的费用流 原来想拆点变成二分图,能配对的连边,跑二分图,可行性未知 后来看到另外一种解法.. 符合匹配要求的数要满足:质因子的个数相差为1,且两者可整除 ...

  6. BZOJ 4514: [Sdoi2016]数字配对 [费用流 数论]

    4514: [Sdoi2016]数字配对 题意: 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数 ...

  7. BZOJ.4514.[SDOI2016]数字配对(费用流SPFA 二分图)

    BZOJ 洛谷 \(Solution\) 很显然的建二分图后跑最大费用流,但有个问题是一个数是只能用一次的,这样二分图两部分都有这个数. 那么就用两倍的.如果\(i\)可以向\(j'\)连边,\(j\ ...

  8. 【BZOJ 4514】[Sdoi2016]数字配对 费用流

    利用spfa流的性质,我直接拆两半,正解分奇偶(妙),而且判断是否整除且质数我用的是暴力根号,整洁判断质数个数差一(其他非spfa流怎么做?) #include <cstdio> #inc ...

  9. 4514: [Sdoi2016]数字配对 费用流

    链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4514 思路 EK直接贪心做 <0的时候加上剩余返回 二分图a->b的时候 把b- ...

  10. bzoj4514 数字配对

    思路 首先想到费用流. 对于每个点拆点.然后考虑我们怎样才能保证每个点只被用一次. 如果\(i\)与\(j\)满足条件.那么就从\(i\)向\(j\)连一条边并且从\(j\)向\(i\)连一条边.这样 ...

随机推荐

  1. 3-5 编程练习:jQuery实现简单的图片对应展示效果

    3-5 编程练习:jQuery实现简单的图片对应展示效果 通过这个章节的学习, 老师带领大家完成了一个基本的图片切换特效,接下来,我们也实现一个类似的效果,点击相应的按钮,切换对应的图片. 效果图 : ...

  2. 三分 HDOJ 3714 Error Curves

    题目传送门 /* 三分:凹(凸)函数求极值 */ #include <cstdio> #include <algorithm> #include <cstring> ...

  3. LN : leetcode 53 Maximum Subarray

    lc 53 Maximum Subarray 53 Maximum Subarray Find the contiguous subarray within an array (containing ...

  4. TI 77GHZ雷达开发套件 RDP-DC100

                                        RDP-DC100用户使用手册           目录 1.      硬件说明... 3 1.1.      官方处理板的修 ...

  5. Shell script之How to write

    Write shell script: 1) Editor like vi or mcedi 2) Set execute permission for your script chmod  perm ...

  6. os下,vs code 自动编译ts

    nodejs安装ts npm install -g typescript 进入工程目录,用命令初始化ts(生成tsconfig.json) tsc --init 如果要指定生成目录,打开tsconfi ...

  7. 07C语言程序语句

    C语言程序语句 判断语句 if(表达式) {语句} #include <stdio.h> int main(){ printf("请输入2个数字:"); int a,b ...

  8. php切换版本之后 redis 安装使用

    一:redis安装Download, extract and compile Redis with: $ wget http://download.redis.io/releases/redis-3. ...

  9. sql之inner join

    这个嘛...经常写sql写的我怀疑自己:算了还是记下来了再强调一遍!再强调一遍!再强调一遍!:虽然很傻逼... inner join(等值连接) 只返回两个表中联结字段相等的行

  10. Listview异步加载图片之优化篇

    在APP应用中,listview的异步加载图片方式能够带来很好的用户体验,同时也是考量程序性能的一个重要指标.关于listview的异步加载,网上其实很多示例了,中心思想都差不多,不过很多版本或是有b ...