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]\) 那么\ ...
随机推荐
- IDEA报错Error:Module 'shop-common' production: java.lang.IndexOutOfBoundsException
问题描述: 本来项目是正常的,编译.运行.启动都是OK的,但是在一次电脑重启后,出现了以上这个问题:Error:Module 'shop-common' production: java.lang.I ...
- codeforces#1090 D. New Year and the Permutation Concatenation(打表找规律)
题意:给出一个n,生成n的所有全排列,将他们按顺序前后拼接在一起组成一个新的序列,问有多少个长度为n的连续的子序列和为(n+1)*n/2 题解:由于只有一个输入,第一感觉就是打表找规律,虽然表打出来了 ...
- 开发工程中遇到的BUG
Xcode7自带Git创建的项目"Couldn’t communicate with a helper application" git xcode7 zhunjiee 2015年 ...
- Django之在Python中调用Django环境
Django之在Python中调用Django环境 新建一个py文件,在其中写下如下代码: import os if __name__ == '__main__': os.environ.setdef ...
- semantic-ui 容器与栅格
semantic中可以指定one-sixteen这16个单词来指定网格column所占的长度.也就是说,在网页中,一行最多只有16个column,超过16个之后,自动移到下一行. 栅格可以使用i,di ...
- Python3练习题 006 冒泡排序
import random a = [random.randint(1,100) for i in range(10)]def bu(target): length = len(target) whi ...
- MyEclipse 配置 Tomcat
安装好Tomcat,MyEclipse 之后,利用这两个工具可以开发部署Web 应用,步骤相对手动部署要简洁的多,这里有一个特别要注意的地方:系统里安装JDK.Tomcat.MyEclipse 的版本 ...
- [转帖]Docker容器CPU、memory资源限制
Docker容器CPU.memory资源限制 https://www.cnblogs.com/zhuochong/p/9728383.html 处理事项内容等 这一块内容感觉 不清楚.. 背景 在使用 ...
- for循环游标
- js 判断一个字符在字符串中出现的次数
<script type="text/javascript"> var s='djh.doiwe.esd.d.ddd0sdd.d.'; var n=(s.split(' ...