bzoj4514 [Sdoi2016]数字配对
Description
Input
Output
一行一个数,最多进行多少次配对
Sample Input
2 4 8
2 200 7
-1 -2 1
Sample Output
HINT
n≤200,ai≤10^9,bi≤10^5,∣ci∣≤10^5
正解:费用流。
这题的费用流模型还是比较显然的,不过有两个要注意的地方。
首先这题需要建成二分图的模型,所以每个点的流量肯定会乘$2$,如果直接连可能会导致有些点多用了流量。对于这种情况,我们在每个$i->j$的连边时,把$j->i$也连边,最后把流量除以$2$,就能解决这个问题了。
还有一个问题,题目是问的费用$>=0$的最大流,首先我们肯定要把费用取反,转成最小费用最大流。然后我们可以在每次增广时加一个特判,如果之前增广的费用+当前费用$>0$,那么我们直接取使得费用$<=0$的最大流量就行了。因为费用流每次都是找最短路增广,所以这样做是对的。
//It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1LL<<60)
#define N (3010)
#define il inline
#define RG register
#define ll long long
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) using namespace std; struct edge{ ll nt,to,flow,cap,dis; }g[]; ll head[N],dis[N],vis[N],f[N],p[N],fa[N],a[N],b[N],c[N];
ll q[],n,S,T,flow,cost,num=; il ll gi(){
RG ll x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il void insert(RG ll from,RG ll to,RG ll cap,RG ll cost){
g[++num]=(edge){head[from],to,,cap,cost},head[from]=num; return;
} il ll bfs(RG ll S,RG ll T){
for (RG ll i=;i<=T;++i) dis[i]=inf;
RG ll h=,t=; q[t]=S,dis[S]=,vis[S]=,f[S]=inf;
while (h<t){
RG ll x=q[++h],v;
for (RG ll i=head[x];i;i=g[i].nt){
v=g[i].to;
if (dis[v]>dis[x]+g[i].dis && g[i].cap>g[i].flow){
dis[v]=dis[x]+g[i].dis,fa[v]=x,p[v]=i;
f[v]=min(f[x],g[i].cap-g[i].flow);
if (!vis[v]) vis[v]=,q[++t]=v;
}
}
vis[x]=;
}
if (dis[T]==inf) return ;
if (cost+dis[T]*f[T]>){ //费用>0特判
RG ll x=-cost/dis[T];
flow+=x; return ;
}
flow+=f[T],cost+=dis[T]*f[T];
for (RG ll i=T;i!=S;i=fa[i])
g[p[i]].flow+=f[T],g[p[i]^].flow-=f[T];
return ;
} il ll isprime(RG ll x){
if (x== || x==) return ;
if (!(x&)) return x==;
for (RG ll i=;i*i<=x;++i)
if (!(x%i)) return ;
return ;
} il void work(){
n=gi(),S=*n+,T=*n+;
for (RG ll i=;i<=n;++i) a[i]=gi();
for (RG ll i=;i<=n;++i) b[i]=gi();
for (RG ll i=;i<=n;++i) c[i]=gi();
for (RG ll i=;i<=n;++i){
insert(S,i,b[i],),insert(i,S,,);
insert(n+i,T,b[i],),insert(T,n+i,,);
}
for (RG ll i=;i<=n;++i)
for (RG ll j=;j<=n;++j){
if (a[i]%a[j]) continue;
if (isprime(a[i]/a[j])){
insert(i,n+j,inf,-c[i]*c[j]),insert(n+j,i,,c[i]*c[j]);
insert(j,n+i,inf,-c[i]*c[j]),insert(n+i,j,,c[i]*c[j]);
//防止多余流量影响结果
}
}
while (bfs(S,T)); printf("%lld\n",flow>>); return;
} int main(){
File("match");
work();
return ;
}
bzoj4514 [Sdoi2016]数字配对的更多相关文章
- BZOJ4514——[Sdoi2016]数字配对
有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci×cj 的 ...
- BZOJ4514[Sdoi2016]数字配对——最大费用最大流
题目描述 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci ...
- bzoj4514 [Sdoi2016]数字配对(网络流)
Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对 ...
- [bzoj4514][SDOI2016]数字配对——二分图
题目描述 传送门 题解: 这个题真的是巨坑,经过了6个WA,2个TLE,1个RE后才终于搞出来,中间都有点放弃希望了... 主要是一定要注意longlong! 下面开始说明题解. 朴素的想法是: 如果 ...
- BZOJ4514 [Sdoi2016]数字配对 【费用流】
题目 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci×c ...
- bzoj4514: [Sdoi2016]数字配对--费用流
看了一眼题目&数据范围,觉得应该是带下界的费用流 原来想拆点变成二分图,能配对的连边,跑二分图,可行性未知 后来看到另外一种解法.. 符合匹配要求的数要满足:质因子的个数相差为1,且两者可整除 ...
- bzoj4514: [Sdoi2016]数字配对(费用流)
传送门 ps:费用流增广的时候费用和流量打反了……调了一个多小时 每个数只能参与一次配对,那么这就是一个匹配嘛 我们先把每个数分解质因数,记质因子总个数为$cnt_i$,那如果$a_i/a_j$是质数 ...
- 【bzoj4514】: [Sdoi2016]数字配对 图论-费用流
[bzoj4514]: [Sdoi2016]数字配对 好像正常的做法是建二分图? 我的是拆点然后 S->i cap=b[i] cost=0 i'->T cap=b[i] cost=0 然后 ...
- 【BZOJ4514】[Sdoi2016]数字配对 费用流
[BZOJ4514][Sdoi2016]数字配对 Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ...
随机推荐
- synchronized的4种用法
1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程 ...
- Dollar Dayz poj3181
http://poj.org/problem?id=3181 这个题目一开始就能看出来是个dp问题,但是我并没有一开始就看出来是一个完全背包为题,只是想着根据以前的方法,这个问题应该是可以找到规律的, ...
- java内部发送http请求并取得返回结果,修改response的cookie
public Object userLogin(HttpServletRequest request, HttpServletResponse response, String email, Stri ...
- curl javaSSm框架中传入json数组的格式方法
curl与java结合传入get.post,head请求, 比如: curl的地址: curl -l 127.0.0.1:8080/spacobj/core/do?acid=100 -H " ...
- spdlog源码阅读 (1): sinks
0. spdlog简单介绍 spdlog 是一个快速的 C++ 日志库,只包含头文件,兼容 C++11.项目地址 特性: 非常快 只包含头文件 无需依赖第三方库 支持跨平台 - Linux / Win ...
- 读书笔记 effective c++ Item 34 区分接口继承和实现继承
看上去最为简单的(public)继承的概念由两个单独部分组成:函数接口的继承和函数模板继承.这两种继承之间的区别同本书介绍部分讨论的函数声明和函数定义之间的区别完全对应. 1. 类函数的三种实现 作为 ...
- 设计模式的征途—1.单例(Singleton)模式
单例模式属于创建型模式的一种,创建型模式是一类最常用的设计模式,在软件开发中应用非常广泛.创建型模式将对象的创建和使用分离,在使用对象时无需关心对象的创建细节,从而降低系统的耦合度,让设计方案更易于修 ...
- 解决VIM编辑器中文乱码
追加如下内容到/etc/vimr (或者不同的用户家目录下的.vimrc文件中) set encoding=utf8filetype plugin indent onsyntax on" s ...
- 在腾讯云上部署Hexo博客
推荐理由 ----搭建个人的空间博客目前深受个人开发者的追捧,然而博客的种类和平台有很多,Hexo是一个开源的静态博客生成器.相比于其他博客而言它只要是web容器就能用.除了闷头专研技术之外,程序员还 ...
- 【Electron】Electron开发入门(二):创建项目Hello Word
创建简单的Electron程序 1.首先,切换到你的项目空间,我的在 D:\ProjectsSpace\ElectronProjects\ElectronTest,ElectronTest是案例项目文 ...