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

/*
这道题本来打算写50分,结果只得了30分,第二部分的自己YY的网络流写错了,原因是没注意要可以转成二分图。
根据题意,如果我们把a[i]质因数分解,那么如果x,y能够建边,那么它们分解出来的个数一定相差1,这样就转成了二分图。
至于题目要求的保证费用要大于等于0,也就是越大越好,我们可以将费用变负,然后跑最小费用,每次增广保证费用不大于0。
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define N 210
#define lon long long
#define inf 1000000000000000LL
using namespace std;
int n,S,T,cnt=,tot,totx,toty,ans;
int a[N],b[N],head[N],fa[N],prime[],fx[N],fy[N];
lon c[N],dis[N];int inq[N],f[];
struct node{
int u,v,f,pre;lon c;
};node e[N*N];
bool judge(int x,int y){
if(!x||!y) return false;
if(x<y) swap(x,y);
if(x%y!=) return false;
x/=y;
for(int i=;i<=tot;i++){
if(prime[i]>=x) break;
if(x%prime[i]==) return false;
}
return true;
}
void add(int u,int v,int f,lon c){
e[++cnt].u=u;e[cnt].v=v;e[cnt].f=f;e[cnt].c=-c;e[cnt].pre=head[u];head[u]=cnt;
e[++cnt].u=v;e[cnt].v=u;e[cnt].f=;e[cnt].c=c;e[cnt].pre=head[v];head[v]=cnt;
}
bool spfa(){
queue<int> q;
memset(inq,,sizeof(inq));
for(int i=S;i<=T;i++) dis[i]=inf;
dis[S]=;inq[S]=;q.push(S);
while(!q.empty()){
int u=q.front();q.pop();inq[u]=;
for(int i=head[u];i;i=e[i].pre){
int v=e[i].v;
if(e[i].f&&dis[v]>dis[u]+e[i].c){
dis[v]=dis[u]+e[i].c;fa[v]=i;
if(!inq[v]){
q.push(v);inq[v]=;
}
}
}
}
return dis[T]!=inf;
}
void min_cost(){
lon cost=;
while(spfa()){
int tmp=;
for(int i=fa[T];i;i=fa[e[i].u])
tmp=min(tmp,e[i].f);
if(cost+dis[T]*tmp<=){
cost+=dis[T]*tmp;ans+=tmp;
for(int i=fa[T];i;i=fa[e[i].u])
e[i].f-=tmp,e[i^].f+=tmp;
}
else {//这个地方不是很懂
ans-=(cost/dis[T]);
return;
}
}
}
int main(){
freopen("menci_pair.in","r",stdin);
freopen("menci_pair.out","w",stdout);
scanf("%d",&n);
S=;T=n+;
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<=n;i++)scanf("%d",&b[i]);
for(int i=;i<=n;i++)scanf("%lld",&c[i]);
for(int i=;i<=;i++){
if(!f[i]) prime[++tot]=i;
for(int j=;j<=tot;j++){
if(i*prime[j]>) break;
f[i*prime[j]]=;
if(i%prime[j]==) break;
}
}
for(int i=;i<=n;i++){
int tmp=a[i],num=;
for(int j=;j<=tot;j++){
while(tmp%prime[j]==) tmp/=prime[j],num++;
if(tmp==) break;
}
if(num&) fx[++totx]=i;
else fy[++toty]=i;
}
for(int i=;i<=totx;i++)
for(int j=;j<=toty;j++)
if(judge(a[fx[i]],a[fy[j]]))
add(fx[i],fy[j],,c[fx[i]]*c[fy[j]]);
for(int i=;i<=totx;i++) add(S,fx[i],b[fx[i]],);
for(int i=;i<=toty;i++) add(fy[i],T,b[fy[i]],);
min_cost();
printf("%d",ans);
return ;
}

数字配对(bzoj 4514)的更多相关文章

  1. AC日记——[Sdoi2016]数字配对 bzoj 4514

    4514 思路: 很受伤现在,,测了那么多次不过的原因就是因为INF不够大: 解法有两种: 解法1: 把n个点按照质因数个数为奇或偶分为两个点集(很容易就可以想到): 然后,按照题目连边跑最大费用流: ...

  2. 图论(费用流):BZOJ 4514 [Sdoi2016]数字配对

    4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 820  Solved: 345[Submit][Status ...

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

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

  4. BZOJ 4514: [Sdoi2016]数字配对

    4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1606  Solved: 608[Submit][Statu ...

  5. 【BZOJ-4514】数字配对 最大费用最大流 + 质因数分解 + 二分图 + 贪心 + 线性筛

    4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 726  Solved: 309[Submit][Status ...

  6. SDOI 2016 数字配对

    题目大意:给定n个数字以及每个数字的个数和权值,将满足条件的数字配对,使得总代价不小于0,且配对最多 最大费用最大流拆点,对于每个点,连一条由S到该点的边,容量为b,花费为0,再连一条到T的边 对于每 ...

  7. [SDOI2016 Round1] 数字配对

    COGS 2221. [SDOI2016 Round1] 数字配对 http://www.cogs.pro/cogs/problem/problem.php?pid=2221 ★★★   输入文件:m ...

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

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

  9. 【bzoj4514】: [Sdoi2016]数字配对 图论-费用流

    [bzoj4514]: [Sdoi2016]数字配对 好像正常的做法是建二分图? 我的是拆点然后 S->i cap=b[i] cost=0 i'->T cap=b[i] cost=0 然后 ...

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

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

随机推荐

  1. 关于mysql无法添加中文数据的问题以及解决方案

    今天弄了一天的mysql数据库,就是被一个mysql数据库乱码的问题给缠住了.现在记录一下这个问题,虽然这个问题不是什么太大的事情,但还是记录一下. 问题是这样的: 1.先在mysql的安装文件当中, ...

  2. 如何在Eclipse配置PyDev插件

    如何在Eclipse配置PyDev插件 | 浏览:1733 | 更新:2014-04-21 11:36 1 2 3 4 5 分步阅读 Eclipse配置PyDev插件 方法/步骤   从 Eclips ...

  3. Android中res/layout文件夹里新建布局文件,R中不生成ID的奇葩错误

    新浪微博:http://weibo.com/u/1928100503 网上看了下,发现大都是xml文件名大写而导致的id不能生成的问题,但在下的问题却不是大小写的问题,在下发现,当你的layout目录 ...

  4. Linux下启用MySQL慢查询

    MySQL在linux系统中的配置文件一般是my.cnf找到[mysqld]下面加上log-slow-queries=/data/mysqldata/slowquery.loglong_query_t ...

  5. solr4.2增量索引之同步(修改,删除,新增)--转载

    原文地址:http://www.jiancool.com/article/12743229775/;jsessionid=14E9B3F1BB33399799884B5C8F15DDE1  solr增 ...

  6. Xor Sum HDU - 4825(01字典序板题)

    #include <iostream> #include <cstdio> #include <sstream> #include <cstring> ...

  7. TortoiseSVN的基本使用方法

    TotoiseSVN的基本使用方法 来源 https://blog.csdn.net/hecongzhen/article/details/37879801 在 项目管理实践教程一.工欲善其事,必先利 ...

  8. [BJWC2018]Border 的四种求法

    description luogu 给一个小写字母字符串\(S\),\(q\)次询问每次给出\(l,r\),求\(s[l..r]\)的\(Border\). solution 我们考虑转化题面:给定\ ...

  9. 【HDU4471】Homework(矩阵快速幂)

    [HDU4471]Homework(矩阵快速幂) 题面 Vjudge 给定一个数列的前\(m\)项,给定一个和前\(t\)项相关的递推式. 有\(q\)个位置的递推式单独给出,求数列第\(n\)项. ...

  10. THUSC2018滚粗记

    THUSC2018滚粗记 前言 大家好,我是\(yyb\),我的博客里又多了一篇滚粗记, 我记得我原来在某篇滚粗记中曾经写过 \(yyb\)还会写很多很多次滚粗记才会有一篇不是滚粗记的东西. 看起来这 ...