zoukankan      html  css  js  c++  java
  • BZOJ 1061 志愿者招募

    http://www.lydsy.com/JudgeOnline/problem.php?id=1061

    思路:可以用不等式的改装变成费用流.

    将不等式列出,如果有负的常数,那么就从等式连向T,如果是正的就从S连向等式,流量为常数,费用为0。

    如果是变量,那么找出都有这个变量的两个等式,从负的连向正的流量为inf的边,如果有费用,那就再加上费用。

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<iostream>
     6 #define inf 0x7fffffff
     7 int tot,go[200005],next[200005],first[200005],flow[200005],cost[200005];
     8 int op[200005],a[200005];
     9 int c[200005],vis[200005],dis[200005];
    10 int S,T,n,m,edge[200005],from[200005],ans;
    11 int read(){
    12     int t=0,f=1;char ch=getchar();
    13     while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    14     while ('0'<=ch&&ch<='9') {t=t*10+ch-'0';ch=getchar();}
    15     return t*f;
    16 }
    17 void insert(int x,int y,int z,int l){
    18     tot++;
    19     go[tot]=y;
    20     next[tot]=first[x];
    21     first[x]=tot;
    22     flow[tot]=z;
    23     cost[tot]=l;
    24 }
    25 void add(int x,int y,int z,int l){
    26     insert(x,y,z,l);op[tot]=tot+1;
    27     insert(y,x,0,-l);op[tot]=tot-1;
    28 }
    29 bool spfa(){
    30     for (int i=S;i<=T;i++) vis[i]=0,dis[i]=0x7fffffff;
    31     int h=1,t=1;vis[S]=1;dis[S]=0;
    32     while (h<=t){
    33         int now=c[h++];
    34         for (int i=first[now];i;i=next[i]){
    35               int pur=go[i];
    36               if (flow[i]&&dis[pur]>dis[now]+cost[i]){
    37                  edge[pur]=i;
    38                  from[pur]=now;
    39                  dis[pur]=dis[now]+cost[i];
    40                  if (vis[pur]) continue;
    41                  vis[pur]=1;
    42                  c[++t]=pur;
    43                 }
    44         }
    45         vis[now]=0;
    46     }
    47     return dis[T]!=0x7fffffff;
    48 }
    49 void updata(){
    50     int mn=0x7fffffff;
    51     for (int i=T;i!=S;i=from[i]){
    52        mn=std::min(mn,flow[edge[i]]);
    53     }
    54     for (int i=T;i!=S;i=from[i]){
    55       ans+=mn*cost[edge[i]];
    56       flow[edge[i]]-=mn;
    57       flow[op[edge[i]]]+=mn;
    58     }
    59 }
    60 int main(){
    61     n=read();m=read();
    62     S=0;T=n+2;
    63     for (int i=1;i<=n;i++) a[i]=read();
    64     for (int i=1;i<=m;i++){
    65          int u=read(),v=read(),c=read();
    66          add(u,v+1,inf,c);
    67     }    
    68     for (int i=1;i<=n+1;i++){
    69          int tmp=a[i]-a[i-1];
    70          if (tmp>=0) add(S,i,tmp,0);
    71          else add(i,T,-tmp,0);
    72          if (i>1) add(i,i-1,inf,0);
    73     }
    74     while (spfa()) updata();
    75     printf("%d
    ",ans);
    76 }
  • 相关阅读:
    Docker 0x05: Dockerfile制作镜像
    Docker 0x04: Docker 基本使用
    Docker 0x03:Install Docker
    Docker 0x02: Docker生态
    Docker 0x01:Docker Container容器技术
    Axios发送AJAX请求
    Django学习之十三:提高页面开发效率减少冗余的模板系统
    javascript获取指定区间范围随机数
    完美解决eclipse编辑器中文字符过小问题
    mysql查询表所有列名,并用逗号分隔
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5612261.html
Copyright © 2011-2022 走看看