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. C++:const_cast的简单理解

    前言:const_cast是我比较头疼的一个知识点,最近查阅了很多资料,也翻看了很多他人的博客,故在此将自己目前学习到的有关const_cast知识做一个简单的总结 一.什么是const_cast 简 ...

  2. 第十一次作业 - Alpha 事后诸葛亮(团队)

    软工 · 第十一次作业 - Alpha 事后诸葛亮(团队) 组长本次作业链接 现代软件工程 项目Postmortem 设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场 ...

  3. 404 Note Found队——现场编程

    目录 组员职责分工 github 的提交日志截图 程序运行截图 程序运行环境 GUI界面 基础功能实现 运行视频 LCG算法 过滤(降权)算法 算法思路 红黑树 附加功能一 背景 实现 附加功能二(迭 ...

  4. 配置resin web方式部署项目

    写在前面,推荐下载resin4.0.47版本.其它版本没有测试 最近打算做一个小项目,然后容器选用了resin.想通过web提交war文件的方式 进行部署,更新代码也方便. 试了resin最新的版本( ...

  5. nexus在linux上搭建

    Maven 仓库的分类:(maven的仓库只有两大类) 1.本地仓库 2.远程仓库,在远程仓库中又分成了3种: 2.1 中央仓库 2.2 私服 2.3 其它公共库 有个maven私服可以很方便地管理我 ...

  6. 【bzoj3576】[Hnoi2014]江南乐 博弈论+SG定理+数学

    题目描述 两人进行 $T$ 轮游戏,给定参数 $F$ ,每轮给出 $N$ 堆石子,先手和后手轮流选择石子数大于等于 $F$ 的一堆,将其分成任意(大于1)堆,使得这些堆中石子数最多的和最少的相差不超过 ...

  7. 【uoj#164】[清华集训2015]V 线段树维护历史最值

    题目描述 给你一个长度为 $n$ 的序列,支持五种操作: $1\ l\ r\ x$ :将 $[l,r]$ 内的数加上 $x$ :$2\ l\ r\ x$ :将 $[l,r]$ 内的数减去 $x$ ,并 ...

  8. Django 2.0 学习(18):Django 缓存、信号和extra

    Django 缓存.信号和extra Django 缓存 由于Django是动态网站,所以每次请求均会去数据库进行相应的操作,当程序访问量大时,耗时必然会显著增加.最简单的解决方法是:使用缓存,缓存将 ...

  9. BZOJ4197 [Noi2015]寿司晚宴 【状压dp】

    题目链接 BZOJ4197 题解 两个人选的数都互质,意味着两个人选择了没有交集的质因子集合 容易想到将两个人所选的质因子集合作为状态\(dp\) \(n\)以内质数很多,但容易发现\(\sqrt{n ...

  10. P3932 浮游大陆的68号岛 【线段树】

    P3932 浮游大陆的68号岛 有一天小妖精们又在做游戏.这个游戏是这样的. 妖精仓库的储物点可以看做在一个数轴上.每一个储物点会有一些东西,同时他们之间存在距离. 每次他们会选出一个小妖精,然后剩下 ...