SPOJ 371 Boxes 最小费用流

来源:互联网 发布:淘宝店最高等级是什么 编辑:程序博客网 时间:2024/04/30 08:19

题目大意:n个盒子围成一圈,第i个盒子里最开始有ai个球。每次可以把一个小球移动到相邻的盒子里。问,想使每个盒子里的球的数目不超过1个,最少移动多少次。

这个题还是比较简单的。源点到每个盒子,连边(s,i,ai,0),每个盒子到汇点建边(i,t,1,0),相邻盒子建边(i,j,∞,1)。

//#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<cmath>#include<cctype>#include<string>#include<algorithm>#include<iostream>#include<ctime>#include<map>#include<set>using namespace std;#define MP(x,y) make_pair((x),(y))#define PB(x) push_back(x)//typedef __int64 LL;//typedef unsigned __int64 ULL;/* ****************** */const int INF=100011122;const double INFF=1e100;const double eps=1e-8;const int mod=9999991;const int NN=1005;const int MM=2000010;/* ****************** */struct G{    int u,v,cap,cost,next;}E[NN*4*2];int p[NN],T;int dd[NN],qw[NN],ff[NN],pre[NN];bool inq[NN];void add(int u,int v,int cap,int cost){    E[T].u=u;    E[T].v=v;    E[T].cap=cap;    E[T].cost=cost;    E[T].next=p[u];    p[u]=T++;    E[T].u=v;    E[T].v=u;    E[T].cap=0;    E[T].cost=-cost;    E[T].next=p[v];    p[v]=T++;}bool find_path(int st,int en,int n,int &flow,int &cost){    int i,u,v,head,tail;    for(i=0;i<=n;i++)    {        dd[i]=INF;        inq[i]=false;    }    head=tail=0;    qw[tail++]=st;    inq[st]=true;    dd[st]=0;    ff[st]=INF;    while(head!=tail)    {        u=qw[head++];        if(head==NN)            head=0;        inq[u]=false;        for(i=p[u];i+1;i=E[i].next)        {            if(E[i].cap>0)            {                v=E[i].v;                if(dd[v]>dd[u]+E[i].cost)                {                    dd[v]=dd[u]+E[i].cost;                    ff[v]=min(ff[u],E[i].cap);                    pre[v]=i;                    if(!inq[v])                    {                        inq[v]=true;                        qw[tail++]=v;                        if(tail==NN)                            tail=0;                    }                }            }        }    }    if(dd[en]==INF)return false;    flow+=ff[en];    cost+=ff[en]*dd[en];    u=en;    while(u!=st)    {        E[ pre[u] ].cap-=ff[en];        E[ pre[u]^1 ].cap+=ff[en];        u=E[ pre[u] ].u;    }    return true;}int MINcost(int st,int en,int n){    int flow=0,cost=0;    while( find_path(st,en,n,flow,cost) );    return cost;}int main(){    int cas;    int i,n,t,ans;    scanf("%d",&cas);    while(cas--)    {        memset(p,-1,sizeof(p));        T=0;        scanf("%d",&n);        for(i=1;i<=n;i++)        {            scanf("%d",&t);            if(t==0)                add(i,n+1,1,0);            else if(t==1)                ;            else            {                add(0,i,t-1,0);            }            add(i,i==1?n:i-1,INF,1);            add(i,i==n?1:i+1,INF,1);        }        ans=MINcost(0,n+1,n+1);        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击