BZOJ4514[Sdoi2016]数字配对——最大费用最大流
题目描述
输入
输出
一行一个数,最多进行多少次配对
样例输入
2 4 8
2 200 7
-1 -2 1
样例输出
提示
n≤200,ai≤10^9,bi≤10^5,∣ci∣≤10^5
有数量上限、有价值,显然费用流,因为题目要求费用不小于$0$,所以用最大费用最大流。将每个点拆成两个点$i$和$i'$,分别与源点和汇点连边,流量为$b[i]$、费用为$0$。枚举任意两个数判断是否能匹配。因为$i$与$j$能匹配,$j$就能与$i$匹配,所以将$i$与$j'$连边、$j$与$i'$连边,流量为$INF$、费用为$-c[i]*c[j]$(因为跑最大费用最大流,边权取反)。每次$SPFA$找到一条增广路,如果加上之后答案满足要求就继续增广,否则就停止。因为一对数的匹配算了两次,所以最后答案除$2$即可。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define INF 1000000000000000ll
#define inf 1000000000
using namespace std;
int head[1000];
int next[100000];
int to[100000];
ll v[100000];
int c[100000];
int f[1000];
int from[100000];
int tot=1;
int S,T;
ll ans;
int n;
int A[300];
int B[300];
int C[300];
queue<int>q;
int vis[1000];
ll d[1000];
int maxflow;
void add(int x,int y,ll z,int w)
{
next[++tot]=head[x];
head[x]=tot;
to[tot]=y;
v[tot]=z;
c[tot]=w;
from[tot]=x;
next[++tot]=head[y];
head[y]=tot;
to[tot]=x;
v[tot]=-z;
c[tot]=0;
from[tot]=y;
}
bool result()
{
int now=T;
int flow=inf;
while(now!=S)
{
flow=min(flow,c[f[now]]);
now=from[f[now]];
}
if(ans+d[T]*flow<=0)
{
ans+=d[T]*flow;
maxflow+=flow;
}
else
{
maxflow+=fabs(ans)/fabs(d[T]);
return 1;
}
now=T;
while(now!=S)
{
c[f[now]]-=flow;
c[f[now]^1]+=flow;
now=from[f[now]];
}
return 0;
}
bool SPFA()
{
for(int i=1;i<=T;i++)
{
d[i]=INF;
}
d[S]=0;
q.push(S);
vis[S]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
vis[now]=0;
for(int i=head[now];i;i=next[i])
{
if(!c[i])
{
continue;
}
if(d[to[i]]>d[now]+v[i])
{
d[to[i]]=d[now]+v[i];
f[to[i]]=i;
if(!vis[to[i]])
{
q.push(to[i]);
vis[to[i]]=1;
}
}
}
}
return d[T]!=INF;
}
void find_max()
{
while(SPFA())
{
if(result())
{
break;
}
}
}
bool check(int x,int y)
{
if(x<y)
{
swap(x,y);
}
if(x%y)
{
return false;
}
int d=x/y;
for(int i=2;i*i<=d;i++)
{
if(d%i==0)
{
return false;
}
}
return true;
}
int main()
{
scanf("%d",&n);
S=2*n+1,T=S+1;
for(int i=1;i<=n;i++)
{
scanf("%d",&A[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&B[i]);
add(S,i,0,B[i]);
add(i+n,T,0,B[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&C[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(check(A[i],A[j]))
{
add(i,n+j,-1ll*C[i]*C[j],1<<30);
add(j,n+i,-1ll*C[i]*C[j],1<<30);
}
}
}
find_max();
printf("%d",maxflow/2);
}
BZOJ4514[Sdoi2016]数字配对——最大费用最大流的更多相关文章
- 【BZOJ-4514】数字配对 最大费用最大流 + 质因数分解 + 二分图 + 贪心 + 线性筛
4514: [Sdoi2016]数字配对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 726 Solved: 309[Submit][Status ...
- BZOJ4514 [Sdoi2016]数字配对 【费用流】
题目 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci×c ...
- 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]数字配对
有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci×cj 的 ...
- bzoj4514 [Sdoi2016]数字配对
Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对 ...
- bzoj4514: [Sdoi2016]数字配对--费用流
看了一眼题目&数据范围,觉得应该是带下界的费用流 原来想拆点变成二分图,能配对的连边,跑二分图,可行性未知 后来看到另外一种解法.. 符合匹配要求的数要满足:质因子的个数相差为1,且两者可整除 ...
- 【BZOJ4514】数字配对(费用流)
题意: 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci× ...
- [SDOI2016]数字配对(费用流+贪心+trick)
重点是如何找到可以配对的\(a[i]\)和\(a[j]\). 把\(a[i]\)分解质因数.设\(a[i]\)分解出的质因数的数量为\(cnt[i]\). 设\(a[i]\geq a[j]\) 那么\ ...
随机推荐
- 基于注解处理器开发自动生成getter和setter方法的插件
昨天无意中,逛到了lombok的网站,并看到了首页的5分钟视频,视频中的作者只是在实体类中写了几个字段,就可以自动编译为含setter.getter.toString()等方法的class文件.看着挺 ...
- C# 对象池的实现(能限制最大实例数量,类似于WCF的MaxInstanceCount功能)
对象池服务可以减少从头创建每个对象的系统开销.在激活对象时,它从池中提取.在停用对象时,它放回池中,等待下一个请求.我们来看下主线程中,如何与对象池打交道: static void Main(stri ...
- 面试 16:栈的压入压出队列(剑指 Offer 第 22 题)
我们今天继续来看看周五留下的习题: 面试题:输入两个整数序列,第一个序列表示栈的压入顺序,请判断二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如:压入序列为{1,2,3,4,5},那{ ...
- 【LeetCode-数组篇】 1 Two Sum
1 前言 之所以开始刷 LeetCode 上的算法题,一是快面临秋招,第二点是因为提升自己的编程能力,坚持两个月,希望博友们监督. 这个系列打算用 C# 和 Java 编程,为什么用两门语言,因为经历 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(90)-EF 扩展操作
上一篇讲了EF直接执行SQL与存储过程的用 法 这次我们来看 EntityFramework-Plus(免费开源) 库的用法相比其他扩展库,这个更加新并且用法更加简单 这是一个对Entity Fram ...
- centos6.5 squid安装
squid作用 1正向代理 标准的代理缓冲服务器,须在每一个内部主机的浏览器上明确指明代理服务器的IP地址和端口号. 透明代理缓冲服务器,代理操作对客户端的浏览器是透明的(即不需指明代理服务器的IP和 ...
- C\S 架构 DNS服务器 交换机 路由器
------------------------只有不快的斧,没有劈不开的柴;只有想不到的人,没有做不到的事.想干总会有办法,不想干总会有理由!# -------------------------- ...
- 接口自动化框架(Pytest+request+Allure)
前言: 接口自动化是指模拟程序接口层面的自动化,由于接口不易变更,维护成本更小,所以深受各大公司的喜爱. 接口自动化包含2个部分,功能性的接口自动化测试和并发接口自动化测试. 本次文章着重介绍第一种, ...
- 基于 Token 的身份验证:JSON Web Token(附:Node.js 项目)
最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twitter,Google+,Github 等等,比起传统的身份验证方法,Token 扩展性更强, ...
- 小P的秘籍
题目描述 小P马上就要来到程序设计大赛的现场.上了,他希望能够AK这次比赛,所以他找到了一个字符串. 这个字符串长度为n,由A和K组成.这个字符串被小p称为AK串.小P任意截取一个区间s,使得这个区间 ...