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 }
人生如梦亦如幻 朝如晨露暮如霞。