看了一眼题目&数据范围,觉得应该是带下界的费用流

原来想拆点变成二分图,能配对的连边,跑二分图,可行性未知

后来看到另外一种解法。。

符合匹配要求的数要满足:质因子的个数相差为1,且两者可整除

因此筛完素数、分解质因子,记录质因子的个数

奇数个分为一类,偶数个分为一类,那么连边一定是奇数向偶数才可以连,而其中能整除的且商为质数的连边

然后源点向奇数的点连边,偶数的点向汇点连边,跑费用流

至于下界,我们先把权值取负

由于是求最小费用,那么当求得费用刚好大于0时

上一次刚好小于零的费用流就是最终的流

答案就是上一次的流量

程序写的不是很简洁。。有些细节比如要开LL值得注意= =

 #include<stdio.h>
 #include<algorithm>
 #include<string.h>
 #include<vector>
 #include<queue>
 #define LL long long
 #define INF 0x7fffffff
 #define maxe 40000*2+10
 #define maxn 1000
 using namespace std;
 struct node{
     int from,to,flow,next;
     LL cost;
 }e[maxe];
 int ans,cnt,head[maxn],pre[maxn],vis[maxn];
 ],odd[maxn],even[maxn];
 LL c[maxn],sum,dis[maxn];
 vector<int> prime;

 void insert(int u, int v, int f, LL c){
     e[++cnt].from=u;
     e[cnt].to=v;
     e[cnt].flow=f;
     e[cnt].cost=c;
     e[cnt].next=head[u];
     head[u]=cnt;
     e[++cnt].from=v;
     e[cnt].to=u;
     e[cnt].flow=;
     e[cnt].cost=-c;
     e[cnt].next=head[v];
     head[v]=cnt;
 }

 void init(){
     scanf("%d", &n);
     ; i<=n; i++) scanf("%d", &a[i]);
     ; i<=n; i++) scanf("%d", &b[i]);
     ; i<=n; i++) scanf("%lld", &c[i]);
 }

 bool judge(int i, int j){
     ;
     int tmp=max(a[i]/a[j], a[j]/a[i]);
     ; k<prime.size(); k++)
         if (prime[k]>=tmp) break;
         ) ;
     ;
 }

 void get_prime(){
     memset(notprime,,sizeof(notprime));
     ; i<=; i++)
         if (!notprime[i]){
             prime.push_back(i);
             ; j+=i)
                 notprime[j]=;
         }
 } 

 void build(){
     odd[]=even[]=;
     ; i<=n; i++){
         ;
         ; j<prime.size(); j++){
             int tmp=a[i];
             ) tmp/=prime[j],sum++;
         }
         ) odd[++odd[]]=i;
         ]]=i;
     }

     cnt=-;
     memset(head,-,sizeof(head));
     memset(e,,sizeof(e));

     ; i<=odd[]; i++)
         ; j<=even[]; j++)
             if (judge(odd[i], even[j]))
                 insert(odd[i],even[j],INF,-c[odd[i]]*c[even[j]]);
     s=n+; t=n+;
     ; i<=odd[]; i++)
         insert(s,odd[i],b[odd[i]],);
     ; i<=even[]; i++)
         insert(even[i],t,b[even[i]],);
 }

 bool spfa(){
     memset(pre,-,sizeof(pre));
     memset(dis,,sizeof(dis));
     queue<int> Q;
     Q.push(s);
     dis[s]=; vis[s]=;
     while (!Q.empty()){
         int now=Q.front();
         Q.pop();
         vis[now]=;
         ; i=e[i].next){
             int v=e[i].to;
              && dis[v]>dis[now]+e[i].cost){
                 dis[v]=dis[now]+e[i].cost;
                 pre[v]=i;
                 if (!vis[v]){
                     vis[v]=;
                     Q.push(v);
                 }
             }
         }
     }
     ) ; ;
 }

 bool flow(){
     int f=INF;
     ; i=pre[e[i^].to]) f=min(f,e[i].flow);
     ){
         ; i=pre[e[i^].to]){
             e[i].flow-=f; e[i^].flow+=f;
         }
         sum+=dis[t]*f;
         ans+=f;
         ;
     }
     else{
         ans-=(sum/dis[t]);
         ;
     }
 }

 void work(){
     ans=; sum=;
     while (spfa() && flow());
     printf("%d\n", ans);
 }

 int main(){
     get_prime();
     init();
     build();
     work();
     ;
 }

bzoj4514: [Sdoi2016]数字配对--费用流的更多相关文章

  1. 【BZOJ4514】[Sdoi2016]数字配对 费用流

    [BZOJ4514][Sdoi2016]数字配对 Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ...

  2. BZOJ 4514: [Sdoi2016]数字配对 [费用流 数论]

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

  3. BZOJ.4514.[SDOI2016]数字配对(费用流SPFA 二分图)

    BZOJ 洛谷 \(Solution\) 很显然的建二分图后跑最大费用流,但有个问题是一个数是只能用一次的,这样二分图两部分都有这个数. 那么就用两倍的.如果\(i\)可以向\(j'\)连边,\(j\ ...

  4. 【BZOJ 4514】[Sdoi2016]数字配对 费用流

    利用spfa流的性质,我直接拆两半,正解分奇偶(妙),而且判断是否整除且质数我用的是暴力根号,整洁判断质数个数差一(其他非spfa流怎么做?) #include <cstdio> #inc ...

  5. 4514: [Sdoi2016]数字配对 费用流

    链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4514 思路 EK直接贪心做 <0的时候加上剩余返回 二分图a->b的时候 把b- ...

  6. BZOJ4514[Sdoi2016]数字配对——最大费用最大流

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

  7. 【BZOJ4514】【SDOI2016】数字配对 [费用流]

    数字配对 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 有 n 种数字,第 i 种数字是 ...

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

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

  9. [bzoj4514]数字配对[费用流]

    今年SDOI的题,看到他们在做,看到过了一百多个人,然后就被虐惨啦... 果然考试的时候还是打不了高端算法,调了...几天 默默地yy了一个费用流构图: 源连所有点,配对的点连啊,所有点连汇... 后 ...

随机推荐

  1. hdu 并查集分类(待续)

    hdu 1829 A Bug's Life 题目大意: 给你n个动物,输入m行a,b,表示a和b应该是异性的,要你判断是否有同性恋. 并查集中,1到n代表应性别,n+1到2n代表一个性别,合并一下,判 ...

  2. 有损FLV视频的画面宽高比修改方案

    问题背景: 需要向网站上发布一条视频新闻,就是新闻只有一段视频.上面给的是一个FLV的视频,大小接近200M,差不多200分钟吧.本来觉得很简单的事,直接上传发布就完了,但是一波三折啊……第一轮上传时 ...

  3. 【虚拟机】苹果虚拟机mac10.11.6+Xcode8.1

    [虚拟机]苹果虚拟机mac10.11.6+Xcode8.1本虚拟机加装Xcode8.1,方便大家更好学习Swift3.0语言以及iOS开发.安装注意事项:第一步:确认硬件:1.确认主板以及cpu支持虚 ...

  4. [工作bug]一个weblogic跨应用导致session丢失的bug之旅

    近来,发布一个应用,开发和本地测试一切都好,一旦部署到测试环境之后,坑爹的问题随之而来,应用程序不定时的超时,导致用户正在操作过程中被踢了出来,纠结了几天,终于在今天将此问题搞定: 1.系统架构 系统 ...

  5. BZOJ 1901 Zju2112 Dynamic Rankings ——整体二分

    [题目分析] 上次用树状数组套主席树做的,这次用整体二分去水. 把所有的查询的结果一起进行二分,思路很好. [代码] #include <cstdio> #include <cstr ...

  6. BZOJ 2631 Tree ——Link-Cut Tree

    [题目分析] 又一道LCT的题目,LCT只能维护链上的信息. [代码] #include <cstdio> #include <cstring> #include <cs ...

  7. mongodb 连接和操作

    使用方法: 1.安装mongodb 2.配置环境变量 mac下: export PATH=/Users/sunbey/Documents/learn/mongodb/mongodb-osx-x86_6 ...

  8. 转:delphi异常捕获try except语句 和 try finally语句用法

    转:http://www.java123.net/v/936977.html      2015-06-24 09:27:48 一直写程序都没管他们,也尽量很少用,今天终于想把他给弄个明白,在网上找来 ...

  9. JavaScript 全局对象

    全局属性和函数可用于所有内建的 JavaScript 对象. 顶层函数(全局函数) 函数 描述 decodeURI() 解码某个编码的 URI. decodeURIComponent() 解码一个编码 ...

  10. DataTable过滤重复字段

    有时我们需要从DataTable中抽取Distinct数据,以前总是以对DataTable进行foreach之类纯手工方式获取. 近来发现DataView可以帮我们直接获取Distinct数据,汗一个 ...