Chocolate
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 622 Accepted Submission(s): 312
Problem Description
Lethe loves eating chocolates very much. In Lethe's birthday, her good friend echo brings N boxes to her, and makes the boxes on the circle. Furthermore, echo tells Lethe that there are many chocolates in the boxes, but the total number of chocolates doesn't exceed N. Also, echo wants Lethe to displace the chocolates in such a way that in each box remains no more than one chocolate. In one move she can shift one chocolate from current box to its neighboring box. (Each box has two neighboring boxes). Can you tell Lethe the minimum number of move to achieve this goal?
Input
There are multi-cases (The total number of cases won't exceed 20). First line is an integer N(1<=N<=500), the total number of boxes. Then N lines follow, each line includes a number, indicates the number of chocolates in the box.
Output
Output the minimum number of move.
Sample Input
10 1 3 3 0 0 2 0 0 0 0
Sample Output
9以前做过的题,重刷题意:有n个盒子,有的盒子有一定数量的巧克力,有的没有,每个盒子可以往邻近的两个盒子传递巧克力,每次至多一个,问最少传递多少次可以使得每个盒子至少有一个巧克力水题 1:超级源点向每个点建边,容量为每个盒子里的巧克力数量,费用为0,2:超级汇点向每个点建边,容量为1,费用为03:每个点向附近的两个盒子建边,容量为INF,因为一个盒子的巧克力数量是可以增多的,所以转移数量不确定,但是费用是确定的,因为每次至多转移一个,所以费用为1,1还有n建边的时候特判一下#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define MAXN 555 #define MAXM 500000 #define INF 0x3f3f3f3f struct node { int u,v,cap,flow,cost,next; }edge[MAXM]; int n,m,top,head[MAXN],cur[MAXN],vis[MAXN],pre[MAXN],num[MAXN],dis[MAXN]; void init() { top=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w,int c) { node E1={u,v,w,0,c,head[u]}; edge[top]=E1; head[u]=top++; node E2={v,u,0,0,-c,head[v]}; edge[top]=E2; head[v]=top++; } void getmap() { for(int i=1;i<=n;i++) { scanf("%d",&num[i]); add(0,i,num[i],0); add(i,n+1,1,0); } for(int i=1;i<=n;i++) { if(i==1) { add(1,2,INF,1); add(1,n,INF,1); } else if(i==n) { add(n,n-1,INF,1); add(n,1,INF,1); } else { add(i,i+1,INF,1); add(i,i-1,INF,1); } } } bool SPFA(int s,int t) { queue<int>q; memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(pre,-1,sizeof(pre)); dis[s]=0; vis[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=edge[i].next) { node E=edge[i]; if(dis[E.v]>dis[E.u]+E.cost&&E.cap>E.flow) { dis[E.v]=dis[E.u]+E.cost; pre[E.v]=i; if(!vis[E.v]) { vis[E.v]=1; q.push(E.v); } } } } return pre[t]!=-1; } void mcmf(int s,int t,int &cost) { cost=0; while(SPFA(s,t)) { int MIN=INF; for(int i=pre[t];i!=-1;i=pre[edge[i^1].v]) { node E=edge[i]; MIN=min(MIN,E.cap-E.flow); } for(int i=pre[t];i!=-1;i=pre[edge[i^1].v]) { edge[i].flow+=MIN; edge[i^1].flow-=MIN; cost+=edge[i].cost*MIN; } } } int main() { while(scanf("%d",&n)!=EOF) { init(); getmap(); int cost=0; mcmf(0,n+1,cost); printf("%d\n",cost); } return 0; }