bzoj4514[Sdoi2016]数字配对

题意:

有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。若两个数字 ai、aj 满足ai 是 aj 的倍数且 ai/aj 是一个质数,那么这两个数字可以配对,并获得 ci×cj 的价值。一个数字只能参与一次配对,可以不参与配对。在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。

题解:

费用流。本题难点是每个数字只能参加一次配对,很容易建错图。正解是先对每个数字分解质因数,按照质因数个数的奇偶建二分图。原因是质因数奇数个和质因数偶数个的两个数相除的商必定不是质数,巧妙地解决了问题。在判断质数方面,如果朴素判断肯定会T,所以可以先筛法求一个质数表,判断的时候直接枚举能否整除质数。因为√109≤32000,所以质数表只要到32000就行了。不过时间复杂度我不会算,本弱太弱了!

题解:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <queue>
 6 #define inc(i,j,k) for(ll i=j;i<=k;i++)
 7 #define ll long long
 8 #define INF 10000000000000000
 9 using namespace std;
10
11 ll p[32000],cnt,mx; bool vis1[32000];
12 void getprime(){
13     cnt=0; memset(vis1,0,sizeof(vis1)); inc(i,2,(ll)sqrt(mx))if(! vis1[i]){
14         p[++cnt]=i; for(ll j=i;j<=(ll)sqrt(mx);j+=i)vis1[j]=1;
15     }
16 }
17 inline bool is_prime(ll x){
18     if(x==1)return 0;
19     inc(i,1,cnt){if(p[i]*p[i]>x)return 1; if(x%p[i]==0)return 0;}
20 }
21 struct e{int f,t;ll c,w;int n;}; e es[1000000]; int ess,g[1000];
22 inline void pe(int f,int t,ll c,ll w){
23     es[++ess]=(e){f,t,c,w,g[f]}; g[f]=ess; es[++ess]=(e){t,f,0,-w,g[t]}; g[t]=ess;
24 }
25 void init(){ess=-1; memset(g,-1,sizeof(g));}
26 queue <int> q; ll d[1000],cost,flow; int fr[1000]; bool inq[1000],vis2[1000];
27 bool spfa(int s,int t){
28     while(! q.empty())q.pop(); memset(vis2,0,sizeof(vis2)); memset(inq,0,sizeof(inq));
29     q.push(s); vis2[s]=1; inq[s]=1; d[s]=0;
30     while(! q.empty()){
31         int x=q.front(); q.pop(); inq[x]=0;
32         for(int i=g[x];i!=-1;i=es[i].n)if(es[i].c&&(!vis2[es[i].t]||d[es[i].t]<d[x]+es[i].w)){
33             vis2[es[i].t]=1; d[es[i].t]=d[x]+es[i].w; fr[es[i].t]=i;
34             if(!inq[es[i].t])q.push(es[i].t),inq[es[i].t]=1;
35         }
36     }
37     if(!vis2[t])return 0;else return 1;
38 }
39 ll maxflowmaxcost(int s,int t){
40     flow=0; cost=0;
41     while(spfa(s,t)){
42         ll a=INF,b=0;for(int i=t;i!=s;i=es[fr[i]].f)a=min(a,es[fr[i]].c);
43         for(int i=t;i!=s;i=es[fr[i]].f)es[fr[i]].c-=a,es[fr[i]^1].c+=a,b+=es[fr[i]].w; cost+=b*a; flow+=a;
44         if(cost<0){flow-=(cost%b==0?cost/b:cost/b+1); break;}
45     }
46     return flow;
47 }
48 ll a[1000],b[1000],c[1000];int n,s,t,sing[1000],doub[1000],tot,singn,doubn;
49 int main(){
50     scanf("%d",&n); inc(i,1,n)scanf("%lld",&a[i]),mx=max(mx,a[i]);
51     inc(i,1,n)scanf("%lld",&b[i]); inc(i,1,n)scanf("%lld",&c[i]);
52     getprime(); s=0; t=n+1; singn=0; doubn=0;
53     inc(i,1,n){
54         int x=a[i]; tot=0; inc(j,1,cnt)if(x%p[j]==0){
55             while(x%p[j]==0)x/=p[j],tot++; if(x==1)break;
56         }
57         if(tot&1)sing[++singn]=i;else doub[++doubn]=i;
58     }
59     init(); inc(i,1,singn)pe(s,sing[i],b[sing[i]],0); inc(i,1,doubn)pe(doub[i],t,b[doub[i]],0);
60     inc(i,1,singn)inc(j,1,doubn)
61         if(max(a[sing[i]],a[doub[j]])%min(a[sing[i]],a[doub[j]])==0&&is_prime(max(a[sing[i]],a[doub[j]])/min(a[sing[i]],a[doub[j]])))
62             pe(sing[i],doub[j],INF,c[sing[i]]*c[doub[j]]);
63     printf("%lld",maxflowmaxcost(s,t));
64     return 0;
65 }

20160422

转载于:https://www.cnblogs.com/YuanZiming/p/5703289.html

bzoj4514[Sdoi2016]数字配对相关推荐

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

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

  2. BZOJ4514 [Sdoi2016]数字配对

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

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

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

  4. P4068 [SDOI2016]数字配对

    P4068 [SDOI2016]数字配对 题目大意 $n$种数字,第$i$种数字是$a_i$​.有$b_i$个,权值是$c_i$ 若两个数字$a_i$​.$a_j$满足,$a_i$是$a_j$的倍数, ...

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

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

  6. 4514: [Sdoi2016]数字配对

    Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对 ...

  7. 【BZOJ4514】数字配对,费用流

    传送门 题面: 写在前面:网络流练习太少-- 思路:费用流,最大或最小随意,看你给费用的符号,建图的话是把数分成两部分,分别是奇数个质因子和偶数个质因子,然后通过题目给出的关系连边(分部分的原因是形成 ...

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

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

  9. 打乱 数字_崔召幼儿园中班悦享时光——亲子益智游戏数字配对

    亲爱的小朋友们,我们已经掌握了简单的,数字宝宝,今天让我们通过已有的数字经验和点数经验来玩一个数字配对的游戏吧! 准备: 1.准备骰子一个,吸管一支,数字1-6卡片. 2.一个鞋盒盖,一个可以装数字卡 ...

最新文章

  1. yii2表单数据检查怎么自定义输出错误_B端产品日记——表单设计
  2. 为什么深度学习几乎成了计算机视觉研究的标配?
  3. C++中public,protected,private派生类继承问题和访问权限问题
  4. mysql索引引擎_mysql搜索引擎和索引那些事
  5. 【WinCE】流设备驱动简介及GPIO驱动的实现
  6. innerHTML和value的区别
  7. excel打开空白_啥?下载的文件显示“文件已损坏,无法打开”?
  8. python的六大数据类型中可以改变_在python中更改数组的数据类型
  9. python 搭建的http 动态服务器_Python3搭建http服务器的实现代码
  10. 苹果手机长截屏_智能长截屏工具,安卓/ios/电脑全平台都给你
  11. matlab 峰值位置,在数据中查找峰值 - MATLAB Simulink - MathWorks 中国
  12. wps复选框怎么设置_wps中excel复选框怎么设置
  13. linux每周2 4 6执行定时任务,linux计划任务crontab例子
  14. mac怎么禁止某个应用联网?
  15. html缓存的图片放在哪里,浏览器图片缓存在哪
  16. 《当咖啡与甘蓝汁竞争》:产品是负熵,帮助客户更好进化
  17. 4 HQL操作之 -- DDL命令
  18. Linux标识第2个扩展分区,精益创业模式与Get Big Fast模式、火箭发射思维模式,对创业假定的不同在于它认为( )。...
  19. Phenix图文流程:使用docking解决Cryo-EM数据的结构问题
  20. java中文乱码终极解决方案

热门文章

  1. dropout的正则化理解
  2. 禁止php 报错怎么做,php – 禁用Laravel错误处理程序
  3. 后端数据操作超时_数据分析在知乎商业质量保障中的初步实践
  4. python中的静态方法如何调用_关于Python中如何使用静态、类、抽象方法的权威指南(译)...
  5. python 网站 源码_在线浏览美图源码,附带python源码
  6. acwing----春季每日一题2022篇(一)
  7. 【项目管理】ITTO-进度管理
  8. 《系统集成项目管理工程师》必背100个知识点-47质量保证人员(QA)的主要工作...
  9. 笔记-项目采购管理-规划采购管理
  10. 转载:越早明白这四个道理越好!