zoukankan      html  css  js  c++  java
  • bzoj4514 [Sdoi2016]数字配对

    Description

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

    Input

    第一行一个整数 n。
    第二行 n 个整数 a1、a2、……、an。
    第三行 n 个整数 b1、b2、……、bn。
    第四行 n 个整数 c1、c2、……、cn。

    Output

     一行一个数,最多进行多少次配对

    Sample Input

    3
    2 4 8
    2 200 7
    -1 -2 1

    Sample Output

    4

    HINT

     n≤200,ai≤10^9,bi≤10^5,∣ci∣≤10^5

    正解:费用流。

    这题的费用流模型还是比较显然的,不过有两个要注意的地方。

    首先这题需要建成二分图的模型,所以每个点的流量肯定会乘$2$,如果直接连可能会导致有些点多用了流量。对于这种情况,我们在每个$i->j$的连边时,把$j->i$也连边,最后把流量除以$2$,就能解决这个问题了。

    还有一个问题,题目是问的费用$>=0$的最大流,首先我们肯定要把费用取反,转成最小费用最大流。然后我们可以在每次增广时加一个特判,如果之前增广的费用+当前费用$>0$,那么我们直接取使得费用$<=0$的最大流量就行了。因为费用流每次都是找最短路增广,所以这样做是对的。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <complex>
     5 #include <cstring>
     6 #include <cstdlib>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <cmath>
    10 #include <queue>
    11 #include <stack>
    12 #include <map>
    13 #include <set>
    14 #define inf (1LL<<60)
    15 #define N (3010)
    16 #define il inline
    17 #define RG register
    18 #define ll long long
    19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    20 
    21 using namespace std;
    22 
    23 struct edge{ ll nt,to,flow,cap,dis; }g[200010];
    24 
    25 ll head[N],dis[N],vis[N],f[N],p[N],fa[N],a[N],b[N],c[N];
    26 ll q[5000010],n,S,T,flow,cost,num=1;
    27 
    28 il ll gi(){
    29     RG ll x=0,q=1; RG char ch=getchar();
    30     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    31     if (ch=='-') q=-1,ch=getchar();
    32     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    33     return q*x;
    34 }
    35 
    36 il void insert(RG ll from,RG ll to,RG ll cap,RG ll cost){
    37     g[++num]=(edge){head[from],to,0,cap,cost},head[from]=num; return;
    38 }
    39 
    40 il ll bfs(RG ll S,RG ll T){
    41     for (RG ll i=1;i<=T;++i) dis[i]=inf;
    42     RG ll h=0,t=1; q[t]=S,dis[S]=0,vis[S]=1,f[S]=inf;
    43     while (h<t){
    44     RG ll x=q[++h],v;
    45     for (RG ll i=head[x];i;i=g[i].nt){
    46         v=g[i].to;
    47         if (dis[v]>dis[x]+g[i].dis && g[i].cap>g[i].flow){
    48         dis[v]=dis[x]+g[i].dis,fa[v]=x,p[v]=i;
    49         f[v]=min(f[x],g[i].cap-g[i].flow);
    50         if (!vis[v]) vis[v]=1,q[++t]=v;
    51         }
    52     }
    53     vis[x]=0;
    54     }
    55     if (dis[T]==inf) return 0;
    56     if (cost+dis[T]*f[T]>0){ //费用>0特判
    57     RG ll x=-cost/dis[T];
    58     flow+=x; return 0;
    59     }
    60     flow+=f[T],cost+=dis[T]*f[T];
    61     for (RG ll i=T;i!=S;i=fa[i])
    62     g[p[i]].flow+=f[T],g[p[i]^1].flow-=f[T];
    63     return 1;
    64 }
    65 
    66 il ll isprime(RG ll x){
    67     if (x==0 || x==1) return 0;
    68     if (!(x&1)) return x==2;
    69     for (RG ll i=2;i*i<=x;++i)
    70     if (!(x%i)) return 0;
    71     return 1;
    72 }
    73 
    74 il void work(){
    75     n=gi(),S=2*n+1,T=2*n+2;
    76     for (RG ll i=1;i<=n;++i) a[i]=gi();
    77     for (RG ll i=1;i<=n;++i) b[i]=gi();
    78     for (RG ll i=1;i<=n;++i) c[i]=gi();
    79     for (RG ll i=1;i<=n;++i){
    80     insert(S,i,b[i],0),insert(i,S,0,0);
    81     insert(n+i,T,b[i],0),insert(T,n+i,0,0);
    82     }
    83     for (RG ll i=1;i<=n;++i)
    84     for (RG ll j=1;j<=n;++j){
    85         if (a[i]%a[j]) continue;
    86         if (isprime(a[i]/a[j])){
    87         insert(i,n+j,inf,-c[i]*c[j]),insert(n+j,i,0,c[i]*c[j]);
    88         insert(j,n+i,inf,-c[i]*c[j]),insert(n+i,j,0,c[i]*c[j]);
    89         //防止多余流量影响结果
    90         }
    91     }
    92     while (bfs(S,T)); printf("%lld
    ",flow>>1); return;
    93 }
    94 
    95 int main(){
    96     File("match");
    97     work();
    98     return 0;
    99 }
  • 相关阅读:
    Create a toolwindow for the VBA editor with .NET(C#).
    批量采集世纪佳缘会员图片及winhttp异步采集效率
    写了一个Windows API Viewer,提供VBA语句的导出功能。提供两万多个API的MSDN链接内容的本地查询
    mysql主从复制
    windows实现MySQL主从复制
    理解“业务逻辑”的含义
    数据库主从复制与读写分离(了解)
    windows下npm安装vue
    phpstorm中配置真正的远程调试(xdebug)
    PHP常量详解:define和const的区别
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6702320.html
Copyright © 2011-2022 走看看