【BZOJ 2879】[Noi2012]美食节 费用流
思路同修车,就是多了一个骚气的操作:动态加边,我们通过spfa流的过程可以知道,我们一次只会跑一流量,最后一层边跑过就不会再悔改,所以说我们只会用到一大片里面的很少的点,所以我们如果可以动态加边的话我们的边的数量就会从n*m*p级别减少到p*n级别,点数的话有些点虽然存在但是由于我们没连上所以就不会有任何用。
这道题告诉我网络流的图并不是静态的他也是可以动态的变化,这道题只是动态得加一些边,还会有什么呢?这道题的动态加边只是为了提高时间效率,还有其他的作用吗?
#include <cstdio> #include <cstring> #include <algorithm> const int N=45; const int M=105; const int P=805; const int O=P*M; const int E=P*M*N*2; const int Inf=0x3f3f3f3f; struct V{ int to,next,c,f; }c[E]; int head[O],t=1; inline void add(int x,int y,int z,int _){ c[++t].to=y,c[t].next=head[x],c[t].f=z,c[t].c=_,head[x]=t; } int dis[O],anc[O],p[N]; int q[O],front,back; bool in[O]; int n,m,sum; int S,T,ans; bool link[M][P]; int val[N][M]; #define food(a) (a) #define cook(a,b) (((a)-1)*sum+(b)+n) inline bool spfa(){ memset(dis,0x3f,sizeof(dis)); dis[S]=0,in[S]=true,q[back++]=S; if(back==O)back=0; while(front!=back){ int x=q[front++];in[x]=false; if(front==O)front=0; for(int i=head[x];i;i=c[i].next) if(c[i].f&&dis[x]+c[i].c<dis[c[i].to]){ dis[c[i].to]=dis[x]+c[i].c,anc[c[i].to]=i; if(!in[c[i].to]){ q[back++]=c[i].to,in[c[i].to]=true; if(back==O)back=0; } } } return dis[T]!=Inf; } inline int shoot(){ int f=Inf; for(int i=anc[T];i;i=anc[c[i^1].to])f=std::min(f,c[i].f); for(int i=anc[T];i;i=anc[c[i^1].to])c[i].f-=f,c[i^1].f+=f; int key=c[anc[T]^1].to-n; int y=key%sum==0?sum:key%sum; int x=(key-y)/sum+1; if(y!=sum&&link[x][y+1]==false){ link[x][y+1]=true; for(int i=1;i<=n;++i){ add(food(i),cook(x,y+1),1,(y+1)*val[i][x]); add(cook(x,y+1),food(i),0,-(y+1)*val[i][x]); } add(cook(x,y+1),T,1,0); add(T,cook(x,y+1),0,0); } return f*dis[T]; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&p[i]),sum+=p[i]; S=sum*m+n+1,T=S+1; for(int i=1;i<=n;++i){ add(S,food(i),p[i],0); add(food(i),S,0,0); } for(int i=1;i<=m;++i){ add(cook(i,1),T,1,0); add(T,cook(i,1),0,0); link[i][1]=true; } for(int i=1,x;i<=n;++i) for(int j=1;j<=m;++j){ scanf("%d",&x); add(food(i),cook(j,1),1,x); add(cook(j,1),food(i),0,-x); val[i][j]=x; } while(spfa())ans+=shoot(); printf("%d",ans); return 0; }
苟利国家生死以, 岂因祸福避趋之。