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\n",ans);
76 }
时间: 2024-10-23 15:18:04

BZOJ 1061 志愿者招募的相关文章

BZOJ 1061 志愿者招募(最小费用最大流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人. 布布通过了解得知,一共有M 类志愿者可以招募.其中第i 类可以从第Si 天工作到第Ti 天,招募费用是每人Ci 元.新官上任三把火,为了出色地完成自己的工作,布

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>

BZOJ 3265 志愿者招募加强版 单纯形

题目大意:同1061 不过每类志愿者能工作的区间是多段 这是卡网络流?不明 总之把1061稍微改改就能过了- - #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define INF 1e10 #define EPS 1e-7 using namespace std; int m,n; namespace

BZOJ 3265 志愿者招募增强版 单

标题效果:同1061 只是间隔为每种类型的志愿工作是多级 这是卡网络流量?未知 所有在所有的1061您将可以更改为在稍微改变- - #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define INF 1e10 #define EPS 1e-7 using namespace std; int m,n;

HYSBZ 1061 志愿者招募 【最小费用流】【差分】【最小费用流模板】

#include<stdio.h> #include<queue> #define MAXN 1003 #define MAXM 10002*4 #define INF 10000000 using namespace std; //起点编号必须最小,终点编号必须最大 bool vis[MAXN]; //spfa中记录是否在队列里边 struct edge{ edge *next,*op; //op是指向反向边 int t,c,v; //t下一个点编号,c容量,v权值 }ES[MA

[线性规划 对偶原理 单纯形] BZOJ 3265 志愿者招募加强版

就是个裸题了 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define cl(x) memset(x,0,sizeof(x)) using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2)

BZOJ 1061 [Noi2008]志愿者招募

1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 2547  Solved: 1600[Submit][Status][Discuss] Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人. 布布通过了解得知,一共有M 类志愿者

BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]

1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3975  Solved: 2421[Submit][Status][Discuss] Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要 Ai 个人. 布布通过了解得知,一共有M 类志

【BZOJ 1061】 [Noi2008]志愿者招募

1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 2066  Solved: 1282 [Submit][Status] Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人. 布布通过了解得知,一共有M 类志愿者可以招募.其中