zoukankan      html  css  js  c++  java
  • bzoj 1061 志愿者招募 有上下界费用流做法

          把每一天看作一个点,每一天的志愿者数目就是流量限制,从i到i+1连边,上下界就是(A[i],+inf)。

          对于每一类志愿者,从T[i]+1到S[i]连边,费用为招募一个志愿者的费用,流量为inf。这样每多1的流量,就多了一个从S[i]到T[i]+1的循环流。

          求一遍无源汇的最小费用可行流就可以了。

          

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #define inf 0x3f3f3f3f
     7 #define N 100005
     8 using namespace std;
     9 int n,m;
    10 int v[N];
    11 int head[N],ver[N],nxt[N],tot,f[N],quan[N];
    12 void add(int a,int b,int c,int d)
    13 {
    14     tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;quan[tot]=d;f[tot]=c;
    15     tot++;nxt[tot]=head[b];head[b]=tot;ver[tot]=a;quan[tot]=-d;f[tot]=0;
    16     return ;
    17 }
    18 int S,T;
    19 int dis[2005],in[2005],with[2005],mn[2005];
    20 bool tell()
    21 {
    22     memset(dis,0x3f,sizeof(dis));
    23     memset(in,0,sizeof(in));
    24     dis[S]=0;mn[S]=inf;
    25     queue<int>q;
    26     q.push(S);
    27     while(!q.empty())
    28     {
    29         int tmp=q.front();q.pop();in[tmp]=0;
    30         for(int i=head[tmp];i;i=nxt[i])
    31         {
    32             if(dis[ver[i]]>dis[tmp]+quan[i]&&f[i])
    33             {
    34                 dis[ver[i]]=dis[tmp]+quan[i];
    35                 with[ver[i]]=i;mn[ver[i]]=min(f[i],mn[tmp]);
    36                 if(!in[ver[i]])in[ver[i]]=1,q.push(ver[i]);
    37             }
    38         }
    39     }
    40     return dis[T]!=inf;
    41 }
    42 int zeng()
    43 {
    44     for(int i=T;i;i=ver[with[i]^1])
    45     {
    46         f[with[i]]-=mn[T];f[with[i]^1]+=mn[T];
    47     }
    48     return mn[T]*dis[T];
    49 }
    50 int main()
    51 {
    52    scanf("%d%d",&n,&m);
    53    S=0;T=n+2;
    54    tot=1;
    55    int tmp;
    56    for(int i=1;i<=n;i++)
    57    {
    58            scanf("%d",&tmp);
    59            add(i,T,tmp,0);
    60         add(S,i+1,tmp,0);
    61         add(i,i+1,inf,0);
    62    }
    63    int t1,t2,t3;
    64    for(int i=1;i<=m;i++)
    65    {
    66          scanf("%d%d%d",&t1,&t2,&t3);
    67          add(t2+1,t1,inf,t3);
    68    }
    69    int ans=0;
    70    while(tell())ans+=zeng();
    71    printf("%d
    ",ans);
    72    return 0;
    73 }

          

  • 相关阅读:
    echarts 算百分比与js toFixed算出来的百分比不一致的问题。
    VUE, Vue Router Tab 显示动态页签名称。
    [日常坑]前端j's数据导出excel,导出的文件损坏
    [最新 | Build 3211]Sublime Text 2.x, 3.x 许可License集合
    图片滤波
    electron-ipc通信性能分析
    设计vue3的请求实体工厂
    canvas-修改图片亮度
    canvas性能-drawImage渲染图片
    基于windows配置gitlab-runner
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6209869.html
Copyright © 2011-2022 走看看