zoukankan      html  css  js  c++  java
  • hdu5076

    好题,首先观察可得w[i][j]选择只有可能两种,一种比阀值大,一种比阀值小

    比阀值大就一定选满足条件最大的w,比阀值小同样一定选满足条件最大的w

    那么一个最小割模型就呼之欲出了,注意w可能是负数那么就集体+1025;

    我们把这两种情况分辨记作w[i][mx[i]],w[i][mi[i]]

    下面是建图,观察两个byte产生收益是or条件似乎不好处理

    但仔细观察连边条件可以发现,二进制只有1位不同意味着byte编号一定可以构成一个二分图

    于是,对于二进制所含1的个数为奇数的i,连边(s,i,w[i][mi[i]]),(i,t,w[i][mx[i]]),而对二进制所含1的个数为偶数的数j则相反

    额外收益即可表示为(i,j,u[i]^u[j])

    那么最大分数=总分数-最小割-n*1025;

    下面就是构造方案了,我一开始sb wa了很久

    首先有的w[i]中不存在比阀值小的情况,那这些byte分配什么value是确定的

    做完最小割后,我们从s沿残流网络做一遍dfs,如果s可以走到i,就意味着(s,i)的边可以不割,(i,t)的边要割

    那么对应点如何选择也就出来了

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 struct way{int flow,po,next;} e[600010];
      5 int p[610],numh[610],h[610],cur[610],pre[610],d[610],cl[610],w[610][610],mx[610],mi[610],ans[610],u[610],b[610];
      6 bool v[610];
      7 int n,m,ln,lm,len,t;
      8 const int lim=1025;
      9 const int inf=1000000007;
     10 
     11 void add(int x,int y,int f)
     12 {
     13      e[++len].po=y;
     14      e[len].flow=f;
     15      e[len].next=p[x];
     16      p[x]=len;
     17 }
     18 void build(int x, int y, int f)
     19 {
     20      add(x,y,f);
     21      add(y,x,0);
     22 }
     23 
     24 int sap()
     25 {
     26     memset(h,0,sizeof(h));
     27     memset(numh,0,sizeof(numh));
     28     numh[0]=t+1;
     29     for (int i=0; i<=t; i++) cur[i]=p[i];
     30     int j,u=0,s=0,neck=inf;
     31     while (h[0]<t+1)
     32     {
     33           d[u]=neck;
     34           bool ch=1;
     35           for (int i=cur[u]; i!=-1; i=e[i].next)
     36           {
     37               j=e[i].po;
     38               if (e[i].flow>0&&h[u]==h[j]+1)
     39               {
     40                  neck=min(neck,e[i].flow);
     41                  cur[u]=i;
     42                  pre[j]=u;  u=j;
     43                  if (u==t)
     44                  {
     45                     s+=neck;
     46                     while (u)
     47                     {
     48                           u=pre[u];
     49                           j=cur[u];
     50                           e[j].flow-=neck;
     51                           e[j^1].flow+=neck;
     52                     }
     53                     neck=inf;
     54                  }
     55                  ch=0;
     56                  break;
     57               }
     58           }
     59           if (ch)
     60           {
     61              if (--numh[h[u]]==0) return s;
     62              int q=-1,tmp=t;
     63              for (int i=p[u]; i!=-1; i=e[i].next)
     64              {
     65                  j=e[i].po;
     66                  if (e[i].flow&&h[j]<tmp)
     67                  {
     68                     tmp=h[j];
     69                     q=i;
     70                  }
     71              }
     72              cur[u]=q; h[u]=tmp+1;
     73              numh[h[u]]++;
     74              if (u)
     75              {
     76                 u=pre[u];
     77                 neck=d[u];
     78              }
     79           }
     80     }
     81     return s;
     82 }
     83 
     84 bool dfs(int x)
     85 {
     86     v[x]=1;
     87     for (int i=p[x]; i>-1; i=e[i].next)
     88     {
     89         int y=e[i].po;
     90         if (!e[i].flow) continue;
     91         if (!v[y]) dfs(y);
     92     }
     93 }
     94 
     95 int main()
     96 {
     97     int cas;
     98     scanf("%d",&cas);
     99     for (int i=0; i<256; i++)
    100     {
    101         for (int j=0; j<8 ;j++)
    102           cl[i]^=(i>>j)&1;
    103     }
    104     while (cas--)
    105     {
    106         scanf("%d%d",&ln,&lm);
    107         n=1<<ln; m=1<<lm;
    108         len=-1; memset(p,255,sizeof(p));
    109         memset(ans,0,sizeof(ans));
    110         for (int i=1; i<=n; i++) scanf("%d",&b[i]);
    111         for (int i=1; i<=n; i++) scanf("%d",&u[i]);
    112         for (int i=1; i<=n; i++)
    113         {
    114             mi[i]=mx[i]=0;
    115             w[i][0]=-lim; b[i]++;
    116             for (int j=1; j<b[i]; j++)
    117             {
    118                 scanf("%d",&w[i][j]);
    119                 if (w[i][mi[i]]<w[i][j]) mi[i]=j;
    120             }
    121             for (int j=b[i]; j<=m; j++)
    122             {
    123                 scanf("%d",&w[i][j]);
    124                 if (w[i][mx[i]]<w[i][j]) mx[i]=j;
    125             }
    126             if (!mi[i]) ans[i]=mx[i];
    127         }
    128         t=n+1;
    129         for (int i=0; i<n; i++)
    130             if (cl[i])
    131             {
    132                 for (int j=0; j<ln; j++)
    133                 {
    134                     int y=i^(1<<j);
    135                     build(i+1,y+1,u[i+1]^u[y+1]);
    136                 }
    137             }
    138         for (int i=1; i<=n; i++)
    139             if (cl[i-1])
    140             {
    141                 build(0,i,w[i][mi[i]]+lim);
    142                 build(i,t,w[i][mx[i]]+lim);
    143             }
    144             else {
    145                 build(0,i,w[i][mx[i]]+lim);
    146                 build(i,t,w[i][mi[i]]+lim);
    147             }
    148         sap();
    149         memset(v,0,sizeof(v));
    150         dfs(0);
    151         for (int i=p[0]; i>-1; i=e[i].next)
    152         {
    153             int x=e[i].po;
    154             if (ans[x]) continue;
    155             if ((v[x]&&cl[x-1])||(!v[x]&&!cl[x-1])) ans[x]=mi[x];
    156             else ans[x]=mx[x];
    157         }
    158         for (int i=1; i<=n; i++)
    159         {
    160             printf("%d",ans[i]-1);
    161             if (i!=n) printf(" "); else puts("");
    162         }
    163     }
    164 }
    View Code
  • 相关阅读:
    npm 安装Vue环境时报错
    WinSCP与SecureCRT
    LeetCode100---Same Tree
    LeetCode404---Sum of Left Leaves
    LeetCode283---Move Zeroes
    LeetCode344---Reverse String
    Java多线程一
    Java知识点总结
    Java泛型
    深入浅出设计模式学习笔记四:单例模式
  • 原文地址:https://www.cnblogs.com/phile/p/6378372.html
Copyright © 2011-2022 走看看