zoukankan      html  css  js  c++  java
  • spoj 371 Boxes

    N个盒子围成一圈,第i个盒子初始时有Ai个小球,每次可以把一个小球从一个盒子移到相邻的两个盒子之一里。问最少移动多少次使得每个盒子中小球的个数不超过1。

    ΣAi<=N.1<=N<=1000.

    最小费用最大流。

    每个盒子作为一个点。

    若Ai>1则从源点向此点连一条容量为Ai,费用为0的边。

    若Ai=0则从此点向汇点连一条容量为1,费用为0的边。

    每个盒子向相邻的两个盒子连容量为正无穷,费用为1的边。

    最小费用最大流即为答案。

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 const int dian=1005;
     8 const int bian=6005;
     9 const int INF=0x3f3f3f3f;
    10 int h[dian],nxt[bian],ver[bian],val[bian],cos[bian],with[dian],minn[dian];
    11 int d[dian],v[dian];
    12 int map[dian];
    13 int n,tot;
    14 int S,T;
    15 void add(int a,int b,int c,int d){
    16     tot++;ver[tot]=b;val[tot]=c;cos[tot]=d;nxt[tot]=h[a];h[a]=tot;
    17     tot++;ver[tot]=a;val[tot]=0;cos[tot]=-d;nxt[tot]=h[b];h[b]=tot;
    18 }
    19 bool tell(){
    20     memset(v,0,sizeof(v));
    21     memset(d,0x3f,sizeof(d));
    22     memset(with,0,sizeof(with));
    23     memset(minn,0x3f,sizeof(minn));
    24     queue<int>q;
    25     q.push(S);
    26     v[S]=1;
    27     d[S]=0;
    28     while(!q.empty()){
    29         int x=q.front();
    30         q.pop();
    31         v[x]=0;
    32         for(int i=h[x];i;i=nxt[i]){
    33             int y=ver[i];
    34             if(d[y]>d[x]+cos[i]&&val[i]){
    35                 d[y]=d[x]+cos[i];
    36                 minn[y]=min(minn[x],val[i]);
    37                 with[y]=i;
    38                 if(!v[y]){
    39                     v[y]=1;
    40                     q.push(y);
    41                 }
    42             }
    43         }
    44     }
    45     if(d[T]==0x3f3f3f3f)
    46         return 0;
    47     return 1;
    48 }
    49 int zeng(){
    50     for(int i=T;i!=S;i=ver[with[i]^1]){
    51         val[with[i]]-=minn[T];
    52         val[with[i]^1]+=minn[T];
    53     }
    54     return minn[T]*d[T];
    55 }
    56 int dinic_cost(){
    57     int r=0;
    58     while(tell())
    59         r+=zeng();
    60     return r;
    61 }
    62 int main(){
    63     int cas;
    64     scanf("%d",&cas);
    65     while(cas--){
    66         memset(h,0,sizeof(h));
    67         memset(nxt,0,sizeof(nxt));
    68         tot=1;
    69         scanf("%d",&n);
    70         S=n+1,T=n+2;
    71         for(int i=1;i<=n;i++)
    72             scanf("%d",&map[i]);
    73         for(int i=1;i<=n;i++){
    74             if(map[i]>1)
    75                 add(S,i,map[i]-1,0);
    76             else if(!map[i])
    77                 add(i,T,1,0);
    78             add(i,(i==1)?n:i-1,INF,1);
    79             add(i,(i==n)?1:i+1,INF,1);
    80         }
    81         printf("%d
    ",dinic_cost());
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    MLlib--FPGrowth算法
    MLlib--SVD算法
    算法--访问单个节点的删除
    算法--环形链表插值
    算法--数组变树
    算法--滑动窗口
    RMAN备份失败之:mount: block device /dev/emcpowerc1 is write-protected, mounting read-only
    OPatch failed with error code 73
    Sybase ASE报错:server Error: 8242, Severity: 16, State: 1
    ORA-00257: archiver error. Connect internal only, until freed
  • 原文地址:https://www.cnblogs.com/dugudashen/p/6223531.html
Copyright © 2011-2022 走看看