bzoj5251 [2018多省省队联测]劈配

直接网络流模拟即可AC。

可持久化+暴力=90分,

可持久化+二分=30分,

暴力加边+二分=100分。

我也很无奈啊。

Ivan便涨红了脸,额上的青筋条条绽出,争辩道,“memcpy也是可持久化……memcpy!……OIer的事,当然是可持久化!”接连便是难懂的话,什么“可持久化无旋Treap套线段树启发式合并”,什么“暴力踩正解”之类,引得众人都哄笑起来。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <queue>
  7 #define N 205
  8 #define inf 0x7fffffff
  9 using namespace std;
 10 struct FLOW{
 11     int e,head[405];
 12     struct edge{
 13         int u,v,f,of,next;
 14     }ed[N*N<<1];
 15     void add(int u,int v,int f){
 16         ed[e].u=u;ed[e].v=v;ed[e].f=f;ed[e].next=head[u];head[u]=e++;
 17         ed[e].u=v;ed[e].v=u;ed[e].f=0;ed[e].next=head[v];head[v]=e++;
 18     }
 19     int dep[405],S,T;
 20     bool bfs(){
 21         memset(dep,0,sizeof dep);
 22         queue<int> q;
 23         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             int v=ed[i].v;
 41             if(ed[i].f&&dep[v]==dep[x]+1){
 42                 int nxt=dfs(v,min(f,ed[i].f));
 43                 ans+=nxt;f-=nxt;ed[i].f-=nxt;ed[i^1].f+=nxt;
 44                 if(!f)break;
 45             }
 46         }
 47         if(!ans)dep[x]=-1;
 48         return ans;
 49     }
 50     int dinic(){
 51         int ans=0;
 52         while(bfs())ans+=dfs(S,inf);
 53         return ans;
 54     }
 55     void init(){
 56         memset(head,0,sizeof head);
 57         e=2;
 58     }
 59 }F,G,NF;
 60 int T,C,n,m,b[N],dr[N],pos[N][N],g[N][N],bo[N],ans[N],pp[N],sum[N];
 61 vector <int> V[N];
 62 int O;
 63 bool cmp(int a,int b){
 64     return g[O][a]<g[O][b];
 65 }
 66 bool check(int x,int i){
 67     NF.init();
 68     NF.S=n+m+1;NF.T=n+m+2;
 69     for(int j=1;j<=m;j++)NF.add(n+j,NF.T,b[j]);
 70     for(int j=1;j<=x;j++){
 71         NF.add(NF.S,j,1);
 72         for(int k=0;k<V[j].size();k++)
 73             NF.add(j,n+V[j][k],1);
 74     }
 75     NF.add(NF.S,i,1);
 76     for(int k=1;k<=m&&g[i][pos[i][k]]<=dr[i];k++)NF.add(i,n+pos[i][k],1);
 77     if(NF.dinic()==sum[x]+1)return 1;
 78     return 0;
 79 }
 80 int main(){
 81     scanf("%d%d",&T,&C);
 82     while(T--){
 83         scanf("%d%d",&n,&m);
 84         for(int i=1;i<=m;i++)scanf("%d",&b[i]);
 85         for(int i=1;i<=n;i++){
 86             for(int j=1;j<=m;j++){
 87                 pos[i][j]=j;
 88                 scanf("%d",&g[i][j]);
 89                 if(!g[i][j])g[i][j]=10000;
 90             }
 91             O=i;
 92             sort(pos[i]+1,pos[i]+m+1,cmp);
 93         }
 94         for(int i=1;i<=n;i++)scanf("%d",&dr[i]);
 95         F.init();
 96         F.S=n+m+1;F.T=F.S+1;
 97         for(int i=1;i<=n;i++)F.add(F.S,i,1);
 98         for(int i=1;i<=m;i++)F.add(n+i,F.T,b[i]);
 99         G=F;
100         for(int i=1;i<=n;i++)V[i].clear();
101         memset(pp,0,sizeof pp);
102         memset(ans,0,sizeof ans);
103         memset(bo,0,sizeof bo);
104         for(int i=1;i<=n;i++){
105             for(int j=1,k=1;j<=m;j=++k){
106                 if(g[i][pos[i][j]]==10000)break;
107                 while(k<m&&g[i][pos[i][k+1]]==g[i][pos[i][j]])k++;
108                 for(int l=j;l<=k;l++)F.add(i,n+pos[i][l],1);
109                 if(F.bfs()&&F.dfs(F.S,inf)==1){
110                     pp[i]=g[i][pos[i][j]];
111                     for(int l=j;l<=k;l++)V[i].push_back(pos[i][l]);
112                     break;
113                 }
114             }
115             if(!pp[i])pp[i]=m+1,sum[i]=sum[i-1];
116             else{
117                 for(int j=0;j<V[i].size();j++)
118                     G.add(i,n+V[i][j],1);
119                 G.bfs();G.dfs(G.S,inf);
120                 sum[i]=sum[i-1]+1;
121             }
122             F=G;
123         }
124         for(int i=1;i<=n;i++){
125             if(g[i][pos[i][1]]>dr[i]){ans[i]=i;continue;}
126             int l=0,r=i-1,mid,fin=0;
127             while(l<=r){
128                 mid=(l+r)>>1;
129                 if(check(mid,i))fin=mid,l=mid+1;
130                 else r=mid-1;
131             }
132             ans[i]=i-r-1;
133         }
134         for(int i=1;i<=n;i++)printf("%d%c",pp[i],((i==n)?'\n':' '));
135         for(int i=1;i<=n;i++)printf("%d%c",ans[i],((i==n)?'\n':' '));
136     }
137     return 0;
138 }
View Code

 

posted @ 2018-04-10 20:04  Ren_Ivan  阅读(241)  评论(0编辑  收藏  举报