[BZOJ2879][Noi2012]美食节

来源:互联网 发布:折800淘宝卖家报名活动 编辑:程序博客网 时间:2024/04/30 06:06

原题地址

题解地址:http://www.cnblogs.com/africamonkey/p/3748118.html

与《修车》题意相同,但要动态加点.

AC code:

#include <cstdio>#include <queue>using namespace std;const int N=100010;const int M=7900010;const int INF=1<<28;int  n,m,p,S,T,cnt=1,ans;int  q[N],head[N],mina[N],minf[N],last[N],num[N];int  ti[1010][1010];bool inq[N],app[N];queue<int> Q;struct Edge{    int v,f,a,next;    Edge() {}    Edge(int v,int f,int a,int next):v(v),f(f),a(a),next(next) {}}E[M];int Min(int x,int y){    return x<y?x:y;}void addedge(int u,int v,int c,int a){    E[++cnt]=Edge(v,c,a,head[u]);    E[++cnt]=Edge(u,0,-a,head[v]);    head[u]=cnt-1;head[v]=cnt;}void read(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++){        scanf("%d",&q[i]);        p+=q[i];    }    S=n+p*m+1;T=S+1;    for(int i=1;i<=n;i++){        addedge(S,i,q[i],0);        for(int j=1;j<=m;j++){            scanf("%d",&ti[i][j]);            addedge(i,n+(j-1)*p+1,1,ti[i][j]);        }    }    for(int i=1;i<=m;i++) addedge(n+(i-1)*p+1,T,1,0);}bool SPFA(){    Q.push(S);    for(int i=1;i<=T;i++) mina[i]=minf[i]=INF;    mina[S]=0;    while(!Q.empty()){        int x=Q.front();        Q.pop();        inq[x]=0;        for(int i=head[x];i;i=E[i].next){            Edge e=E[i];            if((!e.f)||mina[e.v]<=mina[x]+e.a) continue;            num[e.v]=i;            last[e.v]=x;            mina[e.v]=mina[x]+e.a;            minf[e.v]=Min(minf[x],e.f);            if(!inq[e.v]){                inq[e.v]=1;                Q.push(e.v);            }        }    }    if(mina[T]==INF) return 0;    ans+=mina[T]*minf[T];    for(int i=T;i!=S;i=last[i]){        E[num[i]].f-=minf[T];        E[num[i]^1].f+=minf[T];        if(i>n&&i+1<S&&(!app[i+1])){            app[i+1]=1;            int rk=(i+1-n)/p+1,k;            if(!((i+1-n)%p)) rk--;            k=i+1-n-(rk-1)*p;            for(int j=1;j<=n;j++) addedge(j,i+1,1,ti[j][rk]*k);            addedge(i+1,T,1,0);        }    }    return 1;}int main(){    read();    while(SPFA()) ;    printf("%d\n",ans);    return 0;}
0 0
原创粉丝点击