zoukankan      html  css  js  c++  java
  • 【BZOJ4514】【SDOI2016】数字配对 [费用流]

    数字配对

    Time Limit: 10 Sec  Memory Limit: 128 MB
    [Submit][Status][Discuss]

    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

    Solution

      显然是一个费用流,并且这可以是一个二分图,由于 ai/aj 要是质数,那显然可以根据质因子个数的奇偶分类。

      然后跑一跑最大费用最大流。判断一下值要>=0即可统计入答案。mmpBearChild查了一个下午错,发现是INF开小了qaq。

    Code

      1 #include<iostream>    
      2 #include<string>    
      3 #include<algorithm>    
      4 #include<cstdio>    
      5 #include<cstring>    
      6 #include<cstdlib>
      7 #include<cmath>
      8 #include<map>
      9 using namespace std;  
     10 typedef long long s64;
     11   
     12 const int ONE = 205*205;
     13 const int INF = 2147483640;
     14  
     15 int n;
     16 int a[ONE], b[ONE], c[ONE];
     17 s64 dist[ONE];
     18 int vis[ONE], q[ONE*10], pre[ONE];
     19 int first[ONE], go[ONE], next[ONE], pas[ONE], from[ONE], tot;
     20 int pNum[ONE];
     21 int odd[ONE],Onum, eve[ONE],Enum;
     22 int S, T, Ans;
     23 int prime[ONE], isp[ONE], p;
     24 s64 Val, w[ONE];
     25   
     26 int get()
     27 {    
     28         int res=1,Q=1;char c;    
     29         while( (c=getchar())<48 || c>57 ) 
     30         if(c=='-')Q=-1; 
     31         res=c-48;     
     32         while( (c=getchar())>=48 && c<=57 )    
     33         res=res*10+c-48;    
     34         return res*Q;
     35 }
     36 
     37 void Getp(int MaxN)
     38 {
     39         for(int i=2; i <= MaxN; i++)
     40         {
     41             if(!isp[i]) prime[++p] = i;
     42             for(int j=1; j <= prime[p], i*prime[j] <= MaxN; j++)
     43             {
     44                 isp[i * prime[j]] = 1;
     45                 if(i % prime[j] == 0) break;
     46             }
     47         }
     48 }
     49   
     50 int Factor(int x)
     51 {
     52         int res = 0;
     53         while(x != 1)
     54         {
     55             for(int i=1; i<=p; i++)
     56             if(x % prime[i] == 0)
     57             {
     58                 x /= prime[i];
     59                 res++;
     60                 break;
     61             }
     62         }
     63         return res;
     64 }
     65   
     66 int PD(int x, int y)
     67 {
     68         if(x > y) swap(x, y);
     69         if(x==0 || y==0 || y%x!=0) return 0;
     70         x = y / x;
     71         for(int i=2; i<x; i++)
     72         if(x % i == 0) return 0;
     73         return 1;
     74 }
     75   
     76 int Add(int u, int v, int flow, s64 z)
     77 {
     78         next[++tot]=first[u];   first[u]=tot;   go[tot]=v;  pas[tot]=flow;  w[tot]=z;   from[tot]=u;
     79         next[++tot]=first[v];   first[v]=tot;   go[tot]=u;  pas[tot]=0;     w[tot]=-z;  from[tot]=v;
     80 }
     81    
     82 bool Bfs()
     83 {
     84         for(int i=S; i<=T; i++) dist[i] = -1e18;
     85         int tou = 0, wei = 1;
     86         q[1] = S;   vis[S] = 1; dist[S] = 0;
     87         while(tou < wei)
     88         {
     89             int u = q[++tou];
     90             for(int e=first[u]; e; e=next[e])
     91             {
     92                 int v=go[e];
     93                 if(dist[v] < dist[u] + w[e] && pas[e])
     94                 {
     95                     dist[v] = dist[u] + w[e];
     96                     pre[v] = e;
     97                     if(!vis[v])
     98                     {
     99                         q[++wei] = v;
    100                         vis[v] = 1;
    101                     }
    102                 }
    103             }
    104             vis[u] = 0;
    105         }
    106         return dist[T] != -1e18;
    107 }
    108   
    109 void Deal()
    110 {
    111         int x = INF;
    112         for(int e=pre[T]; e; e=pre[from[e]]) x = min(x, pas[e]);
    113         if(Val + dist[T] * x >= 0)
    114         {
    115             for(int e=pre[T]; e; e=pre[from[e]])
    116             {
    117                 pas[e] -= x;
    118                 pas[((e-1)^1)+1] += x;
    119             }
    120             Val += dist[T] * x;
    121             Ans += x;
    122             return;
    123         }
    124         printf("%d", Ans - Val / dist[T]);
    125         exit(0);
    126 }
    127   
    128 int main()
    129 {
    130         Getp(ONE);
    131         n = get();
    132         for(int i=1; i<=n; i++) a[i] = get(), pNum[i] = Factor(a[i]);
    133         for(int i=1; i<=n; i++) b[i] = get();
    134         for(int i=1; i<=n; i++) c[i] = get();
    135           
    136         S = 0; T = n+1;
    137         for(int i=1; i<=n; i++)
    138         {
    139             if(pNum[i] & 1) Add(S,i, b[i],0), odd[++Onum] = i;
    140             else Add(i,T, b[i],0), eve[++Enum] = i;
    141         }
    142           
    143         for(int i=1; i<=Onum; i++)
    144         for(int j=1; j<=Enum; j++)
    145         {
    146             int x = odd[i], y = eve[j];
    147             if( PD(a[x], a[y]) )
    148                 Add(x,y, INF,(s64)c[x]*c[y]);
    149         }
    150         
    151         while(Bfs()) Deal();
    152         printf("%d", Ans - Val / dist[T]);
    153 }
    View Code
  • 相关阅读:
    【BZOJ 4581】【Usaco2016 Open】Field Reduction
    【BZOJ 4582】【Usaco2016 Open】Diamond Collector
    【BZOJ 4580】【Usaco2016 Open】248
    【BZOJ 3754】Tree之最小方差树
    【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版
    【51Nod 1622】【算法马拉松 19C】集合对
    【51Nod 1616】【算法马拉松 19B】最小集合
    【51Nod 1674】【算法马拉松 19A】区间的价值 V2
    【BZOJ 2541】【Vijos 1366】【CTSC 2000】冰原探险
    【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流
  • 原文地址:https://www.cnblogs.com/BearChild/p/6941123.html
Copyright © 2011-2022 走看看