bzoj 2879: [Noi2012]美食节

来源:互联网 发布:淘宝哪家香水是假货 编辑:程序博客网 时间:2024/04/30 07:25

题意:自己看
题解:和修车差不多,但要动态加边。
代码:

#include<bits/stdc++.h>using namespace std;int n,m,p[5000],fst[90000],num=1,s,t,a[5000][10010],dis[90000],flo[90000],pre[90000],nn[10010],ans=0,kk,r[90000];struct edge{    int x,y,c,d,n;}e[400000];bool v[90000];void ins(int x,int y,int c,int d){    e[++num]={x,y,c,d,fst[x]};    fst[x]=num;}int spfa(){    static queue<int>q;    memset(dis,63,sizeof(dis));    memset(flo,0,sizeof(flo));    memset(pre,0,sizeof(pre));    memset(v,0,sizeof(v));    q.push(s);    dis[s]=0;    flo[s]=1<<30;    while(!q.empty())    {        int x=q.front();        v[x]=0;        for(int i=fst[x];i;i=e[i].n)        {            int y=e[i].y;            if(e[i].d&&dis[y]>dis[x]+e[i].c)            {                dis[y]=dis[x]+e[i].c;                pre[y]=i;                flo[y]=min(flo[x],e[i].d);                if(!v[y])                {                    v[y]=1;                    q.push(y);                }            }        }        q.pop();    }    return flo[t];}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)    scanf("%d",&p[i]);    s=0,t=n+m+1;    for(int i=1;i<=n;i++)    {        ins(s,i,0,p[i]);        ins(i,s,0,0);        for(int j=1;j<=m;j++)        {            scanf("%d",&a[i][j]);            ins(i,j+n,a[i][j],1);            ins(j+n,i,-a[i][j],0);        }    }    for(int i=1;i<=m;i++)    {        ins(i+n,t,0,1);        ins(t,i+n,0,0);        nn[i]=1;        r[i+n]=i;    }    kk=t;    int hh;    while(hh=spfa())    {        int oo,pp;        for(int i=pre[t];i;i=pre[e[i].x])        {            if(r[e[i].y])            {                kk++;                ins(kk,t,0,1);                ins(t,kk,0,0);                r[kk]=r[e[i].y];                r[e[i].y]=0;                nn[r[kk]]++;                for(int j=1;j<=n;j++)                {                    ins(j,kk,a[j][r[kk]]*nn[r[kk]],1);                    ins(kk,j,-a[j][r[kk]]*nn[r[kk]],0);                }            }        }        for(int i=pre[t];i;i=pre[e[i].x])        {            e[i].d-=hh;            e[i^1].d+=hh;            ans+=e[i].c*hh;        }/*        for(int i=2;i<=num;i++)        printf("%d %d %d %d\n",e[i].x,e[i].y,e[i].c,e[i].d);        puts("=====");*///      printf("%d %d\n",oo,pp);//      printf("%d\n",ans);    }    printf("%d",ans);}
原创粉丝点击