cogs 2221. [SDOI2016 Round1] 数字配对
★★ 输入文件:pair.in 输出文件:pair.out 简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。
若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数,那么这两个数字可以配对,并获得 ci×cj 的价值。
一个数字只能参与一次配对,可以不参与配对。
在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。
【输入格式】
第一行一个整数 n。
第二行 n 个整数 a1、a2、……、an。
第三行 n 个整数 b1、b2、……、bn。
第四行 n 个整数 c1、c2、……、cn。
【输出格式】
一行一个数,最多进行多少次配对。
【样例输入】
3
2 4 8
2 200 7
-1 -2 1
【样例输出】
4
【提示】
测试点 1 ~ 3:n≤10,ai≤109,bi=1,∣ci∣≤105;
测试点 4 ~ 5:n≤200,ai≤109,bi≤105,ci=0;
测试点 6 ~ 10:n≤200,ai≤109,bi≤105,∣ci∣≤105。
题解:
首先看到让你求匹配,想到网络流中的二分图匹配,然而一个数字只能进行一次匹配,想了很长时间都不知道如何限流,如果直接判断能否匹配是无法确定流量的,正确做法如下:
X1/X2结果是质数,说明讲两个数分解质因数之后,X1的质因子比X2的质因子多1,其余质因子一样。所以X1,X2的质因子的个数的奇偶性不同。由此可以看到,将N个数分解质因数之后,因子数相同的两个数一定不会匹配,所以把数字按照质因子个数分成两个集合,就形成了二分图中的X集和Y集。
二分答案,用最大费用最大流来判断,如果流量等于二分的数值且最大费用大于等于0,则成立。
还有,这题数据范围较坑,inf=1e9还不够。。。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
typedef long long LL;
const LL inf=1e15;
LL a[],b[],c[],d[],N,MAX;
LL prime[],tot;
bool p[][];
vector<LL> X,Y;
struct Edge{
LL to,rest,next,cost;
}e[];
LL head[],cnt=; inline void addedge(LL x,LL y,LL r,LL z){
e[++cnt].to=y; e[cnt].rest=r; e[cnt].cost= z; e[cnt].next=head[x]; head[x]=cnt;
e[++cnt].to=x; e[cnt].rest=; e[cnt].cost=-z; e[cnt].next=head[y]; head[y]=cnt;
} LL S,T,maxflow,mincost,dis[],pre[];
bool vis[]; inline bool SPFA(){
static queue<LL> Q;
while(!Q.empty()) Q.pop();
for(LL i=;i<=T;i++) dis[i]=-inf,vis[i]=false;
Q.push(S); dis[S]=; vis[S]=true;
while(!Q.empty()){
LL x=Q.front(); Q.pop(); vis[x]=false;
for(LL i=head[x];i;i=e[i].next){
LL y=e[i].to;
if(e[i].rest>&&(dis[y]<dis[x]+e[i].cost||dis[y]==-inf)){
dis[y]=dis[x]+e[i].cost;
pre[y]=i;
if(vis[y]==false){
vis[y]=true;
Q.push(y);
}
}
}
}
if(dis[T]>-inf) return true;
return false;
}
inline void update(){
LL flow=inf;
for(LL i=pre[T];i;i=pre[e[i^].to])
flow=min(flow,e[i].rest);
for(LL i=pre[T];i;i=pre[e[i^].to]){
e[i].rest-=flow;
e[i^].rest+=flow;
mincost+=flow*e[i].cost;
}
maxflow+=flow;
}
inline void ASK(){
maxflow=; mincost=;
while(SPFA())
update();
}
inline bool jud(LL x){
S=; T=N+;
for(LL i=;i<=cnt+;i++){
e[i].cost=e[i].next=e[i].rest=e[i].to=;
}
for(LL i=;i<=N+;i++) head[i]=,pre[i]=;
cnt=;
for(LL i=;i<X.size();i++){
addedge(S,X[i],b[X[i]],);
}
for(LL i=;i<X.size();i++){
for(LL j=;j<Y.size();j++){
if(p[X[i]][Y[j]]==true){
addedge(X[i],Y[j],inf,c[X[i]]*c[Y[j]]);
}
}
}
for(LL i=;i<Y.size();i++){
addedge(Y[i],N+,b[Y[i]],);
}
addedge(N+,T,x,);
ASK();
if(mincost>=&&maxflow==x) return true;
return false;
}
inline LL find(LL l,LL r){
if(l+>=r){
if(jud(r)==true) return r;
else return l;
}
LL mid=(l+r)>>;
if(jud(mid)==true) return find(mid,r);
else return find(l,mid-);
}
inline void shai(){
for(LL i=;i<=N;i++){
for(LL j=;j<=N;j++){
if((a[i]>a[j])&&(a[i]%a[j]==)){
LL tmp=a[i]/a[j]; bool hhh=true;
for(LL k=;k*k<=tmp&&k<=tmp;k++){
if(tmp%k==){
hhh=false; break;
}
}
if(hhh==true){
p[i][j]=p[j][i]=true;
// cout<<i<<" "<<j<<endl;
}
}
}
}
}
inline void calc(LL x){
LL tmp=a[x];
for(LL i=;i*i<=tmp&&i<=tmp;i++){
while(tmp%i==){
tmp/=i;
d[x]++;
}
}
if(tmp!=) d[x]++;
}
int main(){
scanf("%lld",&N);
for(LL i=;i<=N;i++) scanf("%lld",&a[i]);
for(LL i=;i<=N;i++) scanf("%lld",&b[i]),MAX+=b[i];
for(LL i=;i<=N;i++) scanf("%lld",&c[i]);
shai();
for(LL i=;i<=N;i++) calc(i);
for(LL i=;i<=N;i++){
if(d[i]%==) X.push_back(i);
else Y.push_back(i);
}
printf("%lld",find(,inf));
return ;
}
cogs 2221. [SDOI2016 Round1] 数字配对的更多相关文章
- Cogs 2221. [SDOI2016 Round1] 数字配对(二分图)
[SDOI2016 Round1] 数字配对 ★★★ 输入文件:menci_pair.in 输出文件:menci_pair.out 简单对比 时间限制:1 s 内存限制:128 MB [题目描述] 有 ...
- [SDOI2016 Round1] 数字配对
COGS 2221. [SDOI2016 Round1] 数字配对 http://www.cogs.pro/cogs/problem/problem.php?pid=2221 ★★★ 输入文件:m ...
- 「SDOI2016」数字配对
「SDOI2016」数字配对 题目大意 传送门 题解 \(a_i\) 是 \(a_j\) 的倍数,且 \(\frac{a_i}{a_j}\) 是一个质数,则将 \(a_i,a_j\) 质因数分解后,其 ...
- 【BZOJ4514】【SDOI2016】数字配对 [费用流]
数字配对 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 有 n 种数字,第 i 种数字是 ...
- [SDOI2016][bzoj4514] 数字配对 [费用流]
题面 传送门 思路 一个数字能且只能匹配一次 这引导我们思考:一次代表什么?代表用到一定上限(b数组)就不能再用,同时每用一次会产生价值(c数组) 上限?价值?网络流! 把一次匹配设为一点流量,那产生 ...
- cogs 2223. [SDOI2016 Round1] 生成魔咒
★★☆ 输入文件:menci_incantation.in 输出文件:menci_incantation.out 简单对比 时间限制:1 s 内存限制:128 MB [题目描述]魔咒串由许多魔咒字符组 ...
- 【LOJ】#2031. 「SDOI2016」数字配对
题解 这个图是个二分图,因为如果有一个奇环的话,我们会发现一个数变成另一个数要乘上个数不同的质数,显然不可能 然后我们发现这个不是求最大流,而是问一定价值的情况下最大流是多少,二分一个流量,加上一条边 ...
- loj2031 「SDOI2016」数字配对
跑最大费用最大流,注意到每次 spfa 出来的 cost 一定是越来越少的,啥时小于 \(0\) 了就停了吧. #include <iostream> #include <cstri ...
- 图论(费用流):BZOJ 4514 [Sdoi2016]数字配对
4514: [Sdoi2016]数字配对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 820 Solved: 345[Submit][Status ...
随机推荐
- FW 编译Android系统源码和内核源码
编译Android系统源码和内核源码 分类: Android2014-07-21 20:58 7287人阅读 评论(28) 收藏 举报 好长时间没有写blog了,之所以没有写,主要还是工作上的事,发现 ...
- 几种常见web攻击手段及其防御方式
XSS(跨站脚本攻击) CSRF(跨站请求伪造) SQL注入 DDOS web安全系列目录 总结几种常见web攻击手段极其防御方式 总结几种常见的安全算法 XSS 概念 全称是跨站脚本攻击(Cross ...
- 002-nginx-在 nginx 反向代理中使用域名,配置动态域名解析
一.概述 代理(proxy),即中间人,它代替客户端发送请求给服务器,收到响应后再转给客户端.通常意义上的代理是从用户的角度讲的,用户通过某个代理可以访问多个网站,这个代理是靠近用户的,比如某些公司可 ...
- ssm返回jsonp数据格式
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数 ...
- (转)Mysql 多表查询详解
MySQL 多表查询详解 一.前言 二.示例 三.注意事项 一.前言 上篇讲到mysql中关键字执行的顺序,只涉及了一张表:实际应用大部分情况下,查询语句都会涉及到多张表格 : 1.1 多表连接有 ...
- mysql 简单主从
主服务器master [root@localhost ~]# vim /etc/my.cnf [mysqld] log-bin=mysql-bin #必须开启log-bin server-id=129 ...
- 使用Python2.7 GET Onenet平台的数据
效果 代码 # -*- coding: utf-8 -*- """ ------------------------------------------------- F ...
- ComBSTR的使用
用 CComBSTR 进行编程 Visual Studio .NET 2003 3(共 3)对本文的评价是有帮助 - 评价此主题 ATL 类 CComBSTR 提供对 BSTR 数据类型的包装 ...
- Keras 源码分析
. │ activations.py │ callbacks.py │ constraints.py │ initializations.py │ metrics.py │ models.py │ o ...
- SVN 取消版本控制并添加至忽略列表
忽略已经版本控制的文件忽略文件和目录 起因: 由于项目中的IDE Jdeveloper在某些指定目录下面会生成server.xml以及common文件夹,且包含一个名为bc4j.xcfg的文件,每次当 ...