zoukankan      html  css  js  c++  java
  • BZOJ4205 : 卡牌配对

    对于两张卡牌,如果存在两种属性值不互质,则可以匹配。

    只考虑200以内的质数,一共有46个,可以新建3*46*46个点来表示一类属性值中有这两种质数的卡牌。

    然后对于每张卡牌,枚举它的质因子,最多只有3个,如此建图求出最大流即可。

    #include<cstdio>
    const int N=66500,inf=~0U>>2,P=201;
    struct edge{int t,f;edge*nxt,*pair;}*g[N],*d[N],pool[3500000],*cur=pool;
    int n,m,i,j,x,y,z,S,T,h[N],gap[N],maxflow;
    int v[P],fac[P][4],cnt,id12[P][P],id13[P][P],id23[P][P],all;
    inline int min(int x,int y){return x<y?x:y;}
    inline void add(int s,int t){
      edge*p=cur++;p->t=t;p->f=1;p->nxt=g[s];g[s]=p;
      p=cur++;p->t=s;p->f=0;p->nxt=g[t];g[t]=p;
      g[s]->pair=g[t];g[t]->pair=g[s];
    }
    int sap(int v,int flow){
      if(v==T)return flow;
      int rec=0;
      for(edge*p=d[v];p;p=p->nxt)if(h[v]==h[p->t]+1&&p->f){
        int ret=sap(p->t,min(flow-rec,p->f));
        p->f-=ret;p->pair->f+=ret;d[v]=p;
        if((rec+=ret)==flow)return flow;
      }
      if(!(--gap[h[v]]))h[S]=T;
      gap[++h[v]]++;d[v]=g[v];
      return rec;
    }
    int main(){
      for(i=2;i<P;i++)if(!v[i])for(cnt++,j=i;j<P;j+=i)v[j]=1,fac[j][++fac[j][0]]=cnt;
      for(i=1;i<=cnt;i++)for(j=1;j<=cnt;j++)id12[i][j]=++all,id13[i][j]=++all,id23[i][j]=++all;
      scanf("%d%d",&n,&m);S=all+n+m+1,T=S+1;
      while(n--){
        add(S,++all);
        scanf("%d%d%d",&x,&y,&z);
        for(i=1;i<=fac[x][0];i++)for(j=1;j<=fac[y][0];j++)add(all,id12[fac[x][i]][fac[y][j]]);
        for(i=1;i<=fac[x][0];i++)for(j=1;j<=fac[z][0];j++)add(all,id13[fac[x][i]][fac[z][j]]);
        for(i=1;i<=fac[y][0];i++)for(j=1;j<=fac[z][0];j++)add(all,id23[fac[y][i]][fac[z][j]]);
      }
      while(m--){
        add(++all,T);
        scanf("%d%d%d",&x,&y,&z);
        for(i=1;i<=fac[x][0];i++)for(j=1;j<=fac[y][0];j++)add(id12[fac[x][i]][fac[y][j]],all);
        for(i=1;i<=fac[x][0];i++)for(j=1;j<=fac[z][0];j++)add(id13[fac[x][i]][fac[z][j]],all);
        for(i=1;i<=fac[y][0];i++)for(j=1;j<=fac[z][0];j++)add(id23[fac[y][i]][fac[z][j]],all);
      }
      for(gap[maxflow=0]=T,i=1;i<=T;i++)d[i]=g[i];
      while(h[S]<T)maxflow+=sap(S,inf);
      return printf("%d",maxflow),0;
    }
    

      

  • 相关阅读:
    Hadoop2.x环境搭建
    HDFS序列化
    Hadoop2.x介绍
    eclipse(1)----ubuntu下的安装与配置
    hive与hbase
    mysql----启动报错
    序列化+protobuff+redis
    爬虫学习笔记(2)--创建scrapy项目&&css选择器
    日常随笔
    spark学习(2)--hadoop安装、配置
  • 原文地址:https://www.cnblogs.com/clrs97/p/4684244.html
Copyright © 2011-2022 走看看