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

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1411  Solved: 535
    [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

    Source

    鸣谢Menci上传

    思路:二分图染色+重新构造二分图+最小费用最大流

    根据题意给各个数连无向边,构成一个森林;

    然后用二分图染色的方法分成两个点集,一个点集连s点,另一个连t点,并对应题意对两个点集内的点连边;

    然后,跑最小费用最大流就好了。(总价值≮0,可以改变费用边权解决)

    数字配对 AAAAAAAAAA 100 C++ 0.032 s 31.24 MB 2017-03-12 21:28:21

    代码实现:

      1 #include<cstdio>
      2 #include<cstring>
      3 #define LL long long
      4 #define inf 1000000000000000ll
      5 LL n,s,t,nf,sf,nw,sw;
      6 int a,b,l;
      7 LL sa[210],sb[210],sc[210];
      8 LL ret;
      9 char ch[30];
     10 int h[210],hs=1;
     11 struct edge{int s,n;LL w,f;}e[900000];
     12 bool pf,v[210],map[210][210];
     13 int ca[210],as,cb[210],bs;
     14 LL f[210];
     15 int q[900000],head,tail;
     16 struct place{int q,l;}p[900000];
     17 inline LL min(LL x,LL y){return x<y?x:y;}
     18 LL read(){
     19     ret=pf=0,l=1;
     20     do{ch[0]=getchar();}while((ch[0]<'0'||ch[0]>'9')&&ch[0]!='-');
     21     if(ch[0]=='-') pf=1,ch[0]=getchar();
     22     do{ch[l++]=getchar();}while(ch[l-1]>='0'&&ch[l-1]<='9');
     23     l-=2;
     24     for(LL i=l,j=1;i>=0;i--,j*=10) ret+=(ch[i]-'0')*j;
     25     if(pf) ret*=-1;
     26     return ret;
     27 }
     28 void write(LL x){
     29     if(!x) return;
     30     write(x/10);
     31     putchar(x%10+'0');
     32 }
     33 bool ps(int x){
     34     for(int i=2;i*i<=x;i++)
     35     if(x%i==0) return 0;
     36     return 1;
     37 }
     38 void dye(int x,int k){
     39     v[x]=1;
     40     if(k==2) ca[as++]=x;
     41     else cb[bs++]=x;
     42     for(int i=h[x];i;i=e[i].n)
     43     if(!v[e[i].s]) dye(e[i].s,k^1);
     44 }
     45 LL SPFA(){
     46     for(int i=s;i<=t;i++) f[i]=inf;
     47     head=tail=0;
     48     q[head++]=s,f[s]=0;
     49     while(head>tail){
     50         a=q[tail++];
     51         for(int i=h[a];i;i=e[i].n)
     52         if(e[i].w&&f[a]+e[i].f<f[e[i].s]){
     53             f[e[i].s]=f[a]+e[i].f;
     54             q[head++]=e[i].s;
     55             p[e[i].s]=(place){a,i};
     56         }
     57     }
     58     return f[t];
     59 }
     60 LL AP(int k,LL w){
     61     if(k==s) return w;
     62     int re=AP(p[k].q,min(w,e[p[k].l].w));
     63     e[p[k].l].w-=re;
     64     e[p[k].l^1].w+=re;
     65     return re;
     66 }
     67 bool Dinic(){
     68     nf=SPFA();
     69     if(nf==inf) return 0; 
     70     nw=AP(t,inf);
     71     if(nf<=0) sw+=nw;
     72     else sw+=min(nw,-sf/nf);
     73     sf+=nf*nw;
     74     if(sf>0) return 0;
     75     else return 1;
     76 }
     77 int main(){
     78     n=read();
     79     s=0,t=n+1;
     80     for(int i=1;i<=n;i++) sa[i]=read();
     81     for(int i=1;i<=n;i++) sb[i]=read();
     82     for(int i=1;i<=n;i++) sc[i]=read();
     83     for(int i=1;i<=n;i++)
     84     for(int j=1;j<=n;j++)
     85     if(sa[j]&&sa[i]%sa[j]==0&&ps(sa[i]/sa[j])){
     86         e[++hs]=(edge){j,h[i]},h[i]=hs;
     87         e[++hs]=(edge){i,h[j]},h[j]=hs;
     88         map[i][j]=map[j][i]=1;
     89     }
     90     for(int i=1;i<=n;i++) if(!v[i]) dye(i,2);
     91     memset(h,0,sizeof(h)),hs=1;
     92     for(int i=0;i<as;i++)
     93     for(int j=0;j<bs;j++)
     94     if(map[ca[i]][cb[j]]){
     95         a=ca[i],b=cb[j];
     96         e[++hs]=(edge){b,h[a],min(sb[a],sb[b]),-sc[a]*sc[b]},h[a]=hs;
     97         e[++hs]=(edge){a,h[b],0,sc[a]*sc[b]},h[b]=hs;
     98     }
     99     for(int i=0;i<as;i++) a=ca[i],e[++hs]=(edge){a,h[s],sb[a],0},h[s]=hs++;
    100     for(int i=0;i<bs;i++) b=cb[i],e[++hs]=(edge){t,h[b],sb[b],0},h[b]=hs++;
    101     while(Dinic());
    102     write(sw);
    103     return 0;
    104 }

    100+的网络流,还不带高级数据结构,呵呵。

    还有long long神烦。

    题目来源:bzoj

  • 相关阅读:
    java基础之System类
    java基础之System类
    java基础之Random类
    java基础之Math类
    java基础之Math类
    java基础之Character类概述
    MySQL数据库
    JavaScript面向对象与原型
    PHP
    sass基础用法
  • 原文地址:https://www.cnblogs.com/J-william/p/6539509.html
Copyright © 2011-2022 走看看