传送门
题面:


写在前面:网络流练习太少……
思路:费用流,最大或最小随意,看你给费用的符号,建图的话是把数分成两部分,分别是奇数个质因子和偶数个质因子,然后通过题目给出的关系连边(分部分的原因是形成二分图,从而分别向源点和汇点连边),费用为(+-)c[i]*c[j](正负号根据跑的是最大费用还是最小费用来决定),流量正无穷,然后两部分分别向源点汇点连边,费用0,流量为b[i]。
注意:
1.两部分连边时需要判断a[i]/a[j]是不是质数,Shallwe的live版程序每次O(a[i]/a[j]−−−−−−√)O(\sqrt {a[i]/a[j]})暴力求解,但当其取极限数据时可达到每次判断O(10^4.5),n2n^2的循环次数不能承受,所以我们可以筛出1-10^4.5的质数,然后每次求a[i]/a[j]是否在这个范围内有质因子就可以判断其是否为质数了
2.费用流终止条件为没有可流的边或费用总和不满足要求,所以我们要记录每次跑完最小(大)费用后的费用总和,且当它要超出规定范围时,我们要把答案加上临界值再退出(比如跑完一次最小费用后,之前答案的费用总和为-4,而这次要增加的为2(流量)*4(本次的费用),那么我们不能全部跑完2个流量,但可以只跑1个流量,所以要ans+=之前的费用总和/本次费用)
3.注意long long,不然会被卡成狗
代码:

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define LL long long
#define Inf 10000000000000LL
using namespace std;
int n,tot=1,s,t;
int a[204],b[204],first[204],One[204],Two[204],up[204];
int prime[10010],ans;
LL dis[204],maxn,c[204];
bool vis[32004];
struct edge
{int u,v,w,next;LL cost;
}e[50000];
queue<int>q;
void add(int x,int y,int z,LL f)
{e[++tot].u=x;e[tot].v=y;e[tot].w=z;e[tot].cost=f;e[tot].next=first[x];first[x]=tot;
}
void init()//筛出1-32000的质数
{for (int i=2;i<=32000;i++){if (!vis[i]) prime[++prime[0]]=i;for (int j=1;j<=prime[0];j++){if (i*prime[j]>32000) break;vis[i*prime[j]]=1;if (i%prime[j]==0) break;}}
}
bool pd(int i,int j)
{if (!a[i]||!a[j]||a[i]%a[j]&&a[j]%a[i]) return 0;int p=max(a[i]/a[j],a[j]/a[i]);for (int k=1;k<=prime[0];k++)if (prime[k]>=p) break;else if (p%prime[k]==0) return 0;return 1;
}
bool spfa()
{memset(dis,127,sizeof(dis));memset(up,0,sizeof(up));dis[s]=0;vis[s]=1;q.push(s);bool yes=0;while (!q.empty()){int x=q.front();q.pop();vis[x]=0;for (int i=first[x];i;i=e[i].next)if (e[i].w&&dis[e[i].v]>dis[x]+e[i].cost){dis[e[i].v]=dis[x]+e[i].cost;up[e[i].v]=i;if (!vis[e[i].v]) vis[e[i].v]=1,q.push(e[i].v);if (e[i].v==t) yes=1;}}if (!yes) return 0;else return 1;
}
bool flow()
{int minn=Inf;for (int i=up[t];i;i=up[e[i].u])minn=min(minn,e[i].w);if (maxn+dis[t]*minn<=0){for (int i=up[t];i;i=up[e[i].u])e[i].w-=minn,e[i^1].w+=minn;ans+=minn;maxn+=dis[t]*minn;return 1;}else {ans-=(maxn/dis[t]);return 0;}
}
main()
{scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d",&a[i]);for (int i=1;i<=n;i++) scanf("%d",&b[i]);for (int i=1;i<=n;i++) scanf("%lld",&c[i]);init();memset(vis,0,sizeof(vis));for (int i=1;i<=n;i++){int k,sum=0;for (int j=1;j<=prime[0];j++){k=a[i];while (k%prime[j]==0) k/=prime[j],sum++;}if (sum&1) One[++One[0]]=i;else Two[++Two[0]]=i;}for (int i=1;i<=One[0];i++)for (int j=1;j<=Two[0];j++)if (pd(One[i],Two[j]))add(One[i],Two[j],Inf,-c[One[i]]*c[Two[j]]),add(Two[j],One[i],0,c[One[i]]*c[Two[j]]);s=n+1;t=n+2;for (int i=1;i<=One[0];i++)add(s,One[i],b[One[i]],0),add(One[i],s,0,0);for (int i=1;i<=Two[0];i++)add(Two[i],t,b[Two[i]],0),add(t,Two[i],0,0);while (spfa()&&flow());printf("%d",ans);
}

【BZOJ4514】数字配对,费用流相关推荐

  1. bzoj4514 [Sdoi2016]数字配对 费用流

    千万不要想复杂了,倍数和质数仅仅是判断两点之间能不能匹配的条件.. 主要问题还是一个分配问题 一开始想贪心,但好像不对,然后就由反例推出了关系图,然后就是二分匹配问题.. 由于每个点入的量+出的量== ...

  2. bzoj4514: [Sdoi2016]数字配对(费用流)

    传送门 ps:费用流增广的时候费用和流量打反了--调了一个多小时 每个数只能参与一次配对,那么这就是一个匹配嘛 我们先把每个数分解质因数,记质因子总个数为$cnt_i$,那如果$a_i/a_j$是质数 ...

  3. [费用流]数字配对,新生舞会

    文章目录 T1:数字配对 题目 题解 CODE T2:新生舞会 题目 题解 CODE(最大费用最大流版) CODE(最小费用最大流版) T1:数字配对 题目 有 n 种数字,第 i 种数字是 ai.有 ...

  4. P4068-[SDOI2016]数字配对【二分,费用流】

    正题 题目链接:https://www.luogu.com.cn/problem/P4068 题目大意 nnn种数字,第iii个是aia_iai​,有bib_ibi​个,价值为ci∗cjc_i*c_j ...

  5. bzoj 4514: [Sdoi2016]数字配对(二分图+费用最大流)

    4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1840  Solved: 703 [Submit][Sta ...

  6. bzoj4514[Sdoi2016]数字配对

    bzoj4514[Sdoi2016]数字配对 题意: 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci.若两个数字 ai.aj 满足ai 是 aj 的倍数且 ai/aj 是一个质数, ...

  7. 【网络流24题】【LOJ6010】数字梯形(费用流)

    problem 给定一个n行的数字梯形,第一行有m个数字 从第一行的每个数字开始往左下或右下移动到底,累加路径上的值 求数字总和最大. 满足限制: 1.路径互不相交 2.路径仅在数字结点处相交 3.路 ...

  8. BZOJ4514 [Sdoi2016]数字配对

    题解 一开始看到这道题各种费用流的即视感. 首先这个配对应该可以想到构建二分图模型.构建出二分图后就比较容易把关系转化为边了. 但怎么构建呢?这个还是比较巧妙的,因为只有 小的数能整除大的数 且商为质 ...

  9. SCUT - 48 - 飞行员的配对方案 - 费用流

    https://scut.online/p/48 一道二分图匹配,跑费用流就可以过了(其实最大流都可以了). #include<bits/stdc++.h> #define MAXN_ 5 ...

最新文章

  1. 面试大法——算法、Python、机器学习等笔试面经资源 | 干货收藏
  2. Redis第一集:Windows下安装Redis和测试
  3. 一款jQuery实现重力弹动模拟效果特效,弹弹弹,弹走IE6
  4. ----==《在路上》==----
  5. GCD Game 博弈论-Nim-质因数应用-质因数个数预处理
  6. java 传递intent_Android中使用Intent在Activity之间传递对象(使用Serializable或者Parcelable)的方法...
  7. DCMTK:将XML文档的内容转换为DICOM结构的报告文件
  8. matlab概率论实验 分别掷硬币1,基于Matlab的概率论仿真实验
  9. 纪中B组模拟赛总结(2020.2.1)
  10. 结构力学计算软件_辽宁网格修复软件价格如何
  11. 9款超级好用的在线PDF工具!
  12. h3c trunk口改access_关于h3c的trunk模式
  13. 靠微信小程序两周获客20万,同城小程序开始爆发
  14. DOTA2新英霸更新日志
  15. vue 使用video加载视频进行展示,视频循环自动播放
  16. 当代著名国际摄影师相关网站大集合
  17. 研究生放假因疫情未按时返回,扣助研补贴!实验室奇葩规定引热议
  18. webrtc服务器开发--搭建环境
  19. 免费的期刊论文文献检索网站(收集整理)
  20. 看完涨薪2K+_____2019 JAVA 必刷面试题

热门文章

  1. 重磅!华为云社区·CSDN【寻找黑马程序员】有奖征文活动奖项公布!!
  2. xtwpro2编程器_xtw100编程器驱动
  3. 红橙Darren视频笔记 状态栏设置颜色 获取高度 设置全屏
  4. Android 替换字体的方式以及同时替换多种字体
  5. Android笔记 几条笔记(未实验)
  6. 2020年日历电子版(打印版)_2020年日历电子版(打印版)79451
  7. Node.js抓取网页信息并展示(cheerio网络爬虫)
  8. ES6_Promise
  9. debian 7 mysql_debian7.2+nginx+mysql
  10. mysql 创建和删除库_mysql入门系列:mysql创建、删除和选择数据库