zoukankan      html  css  js  c++  java
  • bzoj4067 [Ctsc2015]gender

    好神的一道题啊!

    我们发现题目中的ln的贡献非常傻逼,但是我们可以发现这个东西的取值只有40个左右,于是我们可以枚举他!

    枚举完了对于题里的贡献就是一个普通的最小割,采用的是文理分科的思想,与S连代表不改,与T连代表改,然后流量凑一下就可以了。

    那么我们怎么判断我们枚举的值和算出来的方案是否对应呢?我们发现K很小,于是我们可以对于每一层都状压状态,然后通过上面的网络流来计算当这层状态确定时的最优解,然后最后再dp转移一下就可以了。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <queue>
      7 #define N 1050
      8 #define inf 0x3fffffff
      9 using namespace std;
     10 int e=2,head[N];
     11 struct edge{
     12     int u,v,f,next;
     13 }ed[N*N<<1];
     14 void add(int u,int v,int f){
     15     ed[e].u=u;ed[e].v=v;ed[e].f=f;
     16     ed[e].next=head[u];head[u]=e++;
     17     ed[e].u=v;ed[e].v=u;ed[e].f=0;
     18     ed[e].next=head[v];head[v]=e++;
     19 }
     20 int dep[N],S,T;
     21 bool bfs(){
     22     memset(dep,0,sizeof dep);
     23     queue<int> q;q.push(S);dep[S]=1;
     24     while(!q.empty()){
     25         int x=q.front();q.pop();
     26         for(int i=head[x];i;i=ed[i].next){
     27             if(ed[i].f&&!dep[ed[i].v]){
     28                 dep[ed[i].v]=dep[x]+1;
     29                 if(ed[i].v==T)return 1;
     30                 q.push(ed[i].v);
     31             }
     32         }
     33     }
     34     return 0;
     35 }
     36 int dfs(int x,int f){
     37     if(x==T||!f)return f;
     38     int ans=0;
     39     for(int i=head[x];i;i=ed[i].next){
     40         if(ed[i].f&&dep[ed[i].v]==dep[x]+1){
     41             int nxt=dfs(ed[i].v,min(f,ed[i].f));
     42             ans+=nxt;f-=nxt;ed[i].f-=nxt;ed[i^1].f+=nxt;
     43         }
     44     }
     45     if(!ans)dep[x]=-1;
     46     return ans;
     47 }
     48 int dinic(){
     49     int ans=0;
     50     while(bfs())ans+=dfs(S,inf);
     51     return ans;
     52 }
     53 int cnt[20]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
     54 int n,K,m,p,c[N],id[N],x[N],y[N],a[5][55];
     55 int fa[N];
     56 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
     57 struct data{int u,v,w,x;}d[N*10];
     58 bool cmp1(data a,data b){return y[a.u]<y[b.u];}
     59 bool cmp2(int a,int b){return y[a]<y[b];}
     60 char s[N];
     61 int in[N],w[55][17],f[55][215][17],ans;
     62 void getmax(int &x,int y){x>y?x=x:x=y;}
     63 int main(){
     64     scanf("%d%d%d%d%s",&n,&K,&m,&p,s+1);
     65     S=m+1;T=S+1;
     66     register int i,j,k,l,s1,s2,l1,r1,l2,r2,V,now;
     67     for(i=1;i<=m;i++)
     68         scanf("%d",&c[i]),id[i]=fa[i]=i;
     69     for(i=1;i<=K;i++)
     70         for(j=1;j<=n;j++){
     71             scanf("%d",&a[i][j]);
     72             x[a[i][j]]=i;y[a[i][j]]=j;
     73         }
     74     for(i=1;i<=p;i++){
     75         double x;
     76         scanf("%d%d%d%lf",&d[i].u,&d[i].v,&d[i].w,&x);
     77         d[i].x=d[i].w*x;
     78         if(find(d[i].u)!=find(d[i].v))fa[fa[d[i].u]]=fa[d[i].v];
     79     }
     80     for(i=1;i<=m;i++){
     81         if(y[find(i)])y[i]=y[fa[i]];
     82         if(!y[fa[i]]&&y[i])y[fa[i]]=y[i];
     83     }
     84     for(i=1;i<=m;i++){
     85         if(!y[fa[i]])y[fa[i]]=1;
     86         y[i]=y[fa[i]];
     87     }
     88     sort(d+1,d+p+1,cmp1);
     89     sort(id+1,id+m+1,cmp2);
     90     for(l=0;l<=(n-1)*K;l++){
     91         if(!l||(floor(10*log(1.0*l))!=floor(10*log(1.0*(l+1))))){
     92             V=floor(10*log(1.0*(l+1)));
     93             for(i=1,l1=1,r1=0,l2=1,r2=0;i<=n;i++){
     94                 while(r1<p&&y[d[r1+1].u]==i)r1++;
     95                 while(r2<m&&y[id[r2+1]]==i)r2++;
     96                 for(j=0;j<(1<<K);j++){
     97                     e=2;now=head[S]=head[T]=0;
     98                     for(k=l2;k<=r2;k++)in[id[k]]=head[id[k]]=0;
     99                     for(k=l1;k<=r1;k++){
    100                         now+=V*d[k].w*2;
    101                         in[d[k].u]+=V*(d[k].w-d[k].x);
    102                         in[d[k].v]+=V*(d[k].w-d[k].x);
    103                         add(d[k].u,d[k].v,V*(d[k].w+d[k].x));
    104                         add(d[k].v,d[k].u,V*(d[k].w+d[k].x));
    105                     }
    106                     for(k=l2;k<=r2;k++){
    107                         if(!x[id[k]])add(S,id[k],c[id[k]]*2+in[id[k]]),add(id[k],T,0);
    108                         else if(j&(1<<x[id[k]]-1))add(S,id[k],c[id[k]]*2+in[id[k]]),add(id[k],T,inf);
    109                         else add(S,id[k],inf),add(id[k],T,0);
    110                     }
    111                     w[i][j]=(now-dinic())/2;
    112                 }
    113                 l1=r1+1;l2=r2+1;
    114             }
    115         }
    116         memset(f,-0x3f,sizeof f);
    117         for(i=0;i<(1<<K);i++)f[1][0][i]=w[1][i];
    118         for(i=1;i<n;i++)
    119             for(j=0;j<=l&&j<=(i-1)*K;j++)
    120                 for(s1=0;s1<(1<<K);s1++)if(f[i][j][s1]!=f[0][0][0])
    121                     for(s2=0;s2<(1<<K);s2++)
    122                         getmax(f[i+1][j+cnt[s1^s2]][s2],f[i][j][s1]+w[i+1][s2]);
    123         for(i=0;i<(1<<K);i++)ans=max(ans,f[n][l][i]);
    124     }
    125     printf("%d
    ",ans);
    126     return 0;
    127 }
    View Code
  • 相关阅读:
    php mysql增删查改
    php文件上传代码解析
    php验证码
    html加javascript和canvas类似超级玛丽游戏
    javascript图片轮播
    php分页
    《Hadoop权威指南》笔记 第二章 Hadoop Streaming
    《Hadoop权威指南》笔记 第一章&第二章 MapReduce初探
    《深入理解Java虚拟机》笔记 第七章 虚拟机加载机制及双亲委派模型
    《深入理解Java虚拟机》笔记 第三章 内存分配与回收策略
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8824117.html
Copyright © 2011-2022 走看看