传送门

ps:费用流增广的时候费用和流量打反了……调了一个多小时

每个数只能参与一次配对,那么这就是一个匹配嘛

我们先把每个数分解质因数,记质因子总个数为$cnt_i$,那如果$a_i/a_j$是质数当且仅当$cnt_i=cnt_j+1$且$a_i/a_j==0$

那么我们根据$cnt_i$的奇偶性把所有数分为两类,不难发现奇偶性相同的一类是不可能互相配对的,那么这就可以变成一个二分图了

很好,那么跑一个最大费用最大流就可以了

才怪……

费用流是先保证最大流再保证最大费用,并不能保证费用大于等于0

那么我们考虑贪心。每一次spfa的时候我们都找出一条费用最大的通路,而且每一次的最长路都不会大于之前的最长路。所以我们每一次沿着最长路,在价值总和不小于0的情况下尽可能的增加流量。如果找不到通路或者继续增广会使价值总和小于0,那么就退出

可以保证这个贪心一定正确

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<queue>
 6 #include<cmath>
 7 #define int long long
 8 #define inf 0x3f3f3f3f3f3f3f3f
 9 using namespace std;
10 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
11 char buf[1<<21],*p1=buf,*p2=buf;
12 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
13 inline int read(){
14     #define num ch-'0'
15     char ch;bool flag=0;int res;
16     while(!isdigit(ch=getc()))
17     (ch=='-')&&(flag=true);
18     for(res=num;isdigit(ch=getc());res=res*10+num);
19     (flag)&&(res=-res);
20     #undef num
21     return res;
22 }
23 const int N=205,M=500005;
24 int head[N],Next[M],ver[M],edge[M],flow[M],tot=1;
25 inline void add(int u,int v,int e,int f){
26     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e,flow[tot]=f;
27     ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=-e,flow[tot]=0;
28 }
29 int solve(int n){
30     int tot=0,s=sqrt(n);
31     for(int i=2;i<=s&&i<=n;++i)
32     while(n%i==0) ++tot,n/=i;if(n>1) ++tot;
33     return tot;
34 }
35 int dis[N],S,T,vis[N],Pre[N],ans,sum,n;
36 int a[N],b[N],c[N],cnt[N];
37 queue<int> q;
38 bool spfa(){
39     for(int i=S;i<=T;++i) vis[i]=0,dis[i]=-inf;
40     q.push(S),vis[S]=1,dis[S]=0,Pre[T]=-1;
41     while(!q.empty()){
42         int u=q.front();q.pop();vis[u]=0;
43         for(int i=head[u];i;i=Next[i]){
44             int v=ver[i];
45             if(flow[i]&&dis[v]<dis[u]+edge[i]){
46                 dis[v]=dis[u]+edge[i],Pre[v]=i;
47                 if(!vis[v]) q.push(v),vis[v]=1;
48             }
49         }
50     }
51     return ~Pre[T];
52 }
53 bool add_flow(){
54     int fl=inf,f;
55     for(int i=Pre[T];i;i=Pre[ver[i^1]])
56     cmin(fl,flow[i]);f=dis[T]*fl;
57     if(sum+f>=0){
58         sum+=f,ans+=fl;
59         for(int i=Pre[T];i;i=Pre[ver[i^1]])
60         flow[i]-=fl,flow[i^1]+=fl;return 1;
61     }
62     else return ans+=sum/(-dis[T]),0;
63 }
64 int dinic(){
65     while(spfa()&&add_flow());return ans;
66 }
67 signed main(){
68     //freopen("testdata.in","r",stdin);
69     n=read();
70     for(int i=1;i<=n;++i) a[i]=read();
71     for(int i=1;i<=n;++i) b[i]=read();
72     for(int i=1;i<=n;++i) c[i]=read();
73     S=0,T=n+1;
74     for(int i=1;i<=n;++i) cnt[i]=solve(a[i]);
75     for(int i=1;i<=n;++i)
76     cnt[i]&1?add(S,i,0,b[i]):add(i,T,0,b[i]);
77     for(int i=1;i<=n;++i)
78     if(cnt[i]&1)
79     for(int j=1;j<=n;++j)
80     if((cnt[i]+1==cnt[j]&&a[j]%a[i]==0)||
81         (cnt[j]+1==cnt[i]&&a[i]%a[j]==0))
82         add(i,j,c[i]*c[j],inf);
83     printf("%lld\n",dinic());
84     return 0;
85 }

转载于:https://www.cnblogs.com/bztMinamoto/p/9580706.html

bzoj4514: [Sdoi2016]数字配对(费用流)相关推荐

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

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

  2. bzoj4514[Sdoi2016]数字配对

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

  3. BZOJ4514 [Sdoi2016]数字配对

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

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

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

  5. P4068 [SDOI2016]数字配对

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

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

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

  7. 4514: [Sdoi2016]数字配对

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

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

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

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

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

最新文章

  1. PyTorch如何构建和实验神经网络
  2. 10年磨一剑,软件编程走火入魔之:把简单的功能做个彻彻底底、把劳动成果重复利用...
  3. AltiumDesigner 热焊盘铺铜
  4. Exchange2003-2010迁移系列之七
  5. 奥鹏南开大学18春学期计算机作业,南开18春1709、1803学期《办公自动化基础》在线作业答案.doc...
  6. ABAP:关于文本(Read_text,Save_text)
  7. 还在跟面试官纠缠redis分布式锁的问题?此图让你吊打面试官
  8. nagios监控单网卡双IP
  9. JDBC 出现references non-existing project XXX, launch configuration问题的解决办法
  10. Windows下,MySQL root用户忘记密码解决方案
  11. python数据库sqlite3_Python 操作 SQLite 数据库
  12. seaborn 绘图sns.relplot
  13. USB 重定向库usbredir的移植到Android下使用的方法总结
  14. C++控制输出对齐---setw()函数
  15. 什么是六类网线和超六类网线?
  16. python写spark的效率问题_“大数据架构”Spark 3.0发布,重大变化,性能提升18倍...
  17. 年度新旗舰南卡Runner Pro4骨传导耳机评测,解放双耳,运动不设限
  18. 管出来的老公嘴服,疼出来的老公心服
  19. android kodi,XBMC之Android硬解之路
  20. STC12C5A60S2软件模式SPI读取DS1302时钟实时显示在1602

热门文章

  1. 电脑重置后我的电脑没有了怎么办_笔记本电脑没有声音怎么办?
  2. cmake list all directories
  3. DX学习笔记之Surfaces
  4. 机器学习在植物病害识别研究中的应用
  5. 图书馆用文本文件booklist.txt记录图书的书目,其中包括book1,book2,.....,book10.现在又要采购一批新书,编写程序将新的书目添加到目录中。
  6. java exception信息_可能通过Java Exceptions暴露敏感信息?
  7. 毕业设计项目,微博语料情感分析,文本分类
  8. 【项目.源码】深度学习实现任意风格任意内容的极速风格迁移
  9. 卷积神经网络的卷积核大小、个数,卷积层数如何确定呢?
  10. java package 路径_java文件路径问题及Eclipse package,source folder,folder区别及相互转换...