【网络流】【BZOJ1061】【NOI2008】志愿者招募
2017-03-22 10:59
309 查看
原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1061
题意:问你如何购买志愿者使得满足题意的总费用最小。
解题思路:首先,由于志愿者存在的时间是一个区间,我们考虑使用差分序列,这样的话我们就可以比较轻松的建图跑一遍最小费用最大流了。我们定义每个中间点代表着每一天,显然第i天需要的志愿者是i-1天的志愿者+x,用差分即可完成。建图方式详见AC代码。
附:AC代码(因为我比较蒻,所以打了low的一逼的SPFAcostflow,所以跑的巨慢。)
题意:问你如何购买志愿者使得满足题意的总费用最小。
解题思路:首先,由于志愿者存在的时间是一个区间,我们考虑使用差分序列,这样的话我们就可以比较轻松的建图跑一遍最小费用最大流了。我们定义每个中间点代表着每一天,显然第i天需要的志愿者是i-1天的志愿者+x,用差分即可完成。建图方式详见AC代码。
附:AC代码(因为我比较蒻,所以打了low的一逼的SPFAcostflow,所以跑的巨慢。)
#include<stdio.h> #include<string.h> #define S 0 #define T 1002 #define MAXN 1005 #define inf 0x7fffffff #define min(a,b) (a<b?a:b) struct zxy{int to,next,v,c;}edge[35000]; int n,m,cnt=1,head[MAXN],dis[MAXN],pre[MAXN],que[MAXN]; bool vis[MAXN]; inline void ins(int x,int y,int v,int l){ edge[++cnt].to=y,edge[cnt].c=l,edge[cnt].v=v,edge[cnt].next=head[x],head[x]=cnt; } inline void insw(int x,int y,int v,int l){ins(x,y,v,l); ins(y,x,0,(-1)*l);} inline int in(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') f=ch=='-'?-1:1,ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } inline bool SPFA_costflow(int s,int e){ register int h=0,t=1,w,v; memset(dis,127/3,sizeof(dis)); dis[s]=0,vis[s]=1,que[1]=s; while(h!=t){ (++h)%=MAXN; w=que[h]; for (register int i=head[w]; i; i=edge[i].next){ v=edge[i].to; if (dis[v]>dis[w]+edge[i].c&&edge[i].v){ dis[v]=dis[w]+edge[i].c;pre[v]=i; if (!vis[v]){ vis[v]=1; if (dis[v]<dis[que[h+1]]){ que[h]=v;h=(h-1+MAXN)%MAXN; } else{ (++t)%=MAXN;que[t]=v; } } } } vis[w]=0; } return dis[e]!=dis[MAXN-1]; } int costflow(int s,int t){ int cost=0; while(SPFA_costflow(s,t)){ int mi=inf; for (register int i=t; i; i=edge[pre[i]^1].to) mi=min(mi,edge[pre[i]].v); for (register int i=t; i; i=edge[pre[i]^1].to) edge[pre[i]].v-=mi,edge[pre[i]^1].v+=mi; cost+=mi*dis[t]; } return cost; } void init(){ n=in(),m=in();int x=0,pre=0; for (int i=1; i<=n; ++i){ register int t=in(); x=t-pre;pre=t; if (x>0) insw(S,i,x,0); else insw(i,T,(-1)*x,0); insw(i+1,i,inf,0); } insw(n+1,T,inf,0); for (register int i=1; i<=m; ++i){ register int l=in(),r=in(),v=in(); insw(l,r+1,inf,v); } } int main(){ init(); printf("%d",costflow(S,T)); }
相关文章推荐
- [bzoj1061][Noi2008]志愿者招募【网络流】【线性规划】
- bzoj1061 [Noi2008]志愿者招募(网络流解决线性规划问题)
- BZOJ 1061: [Noi2008]志愿者招募(线性规划与网络流)
- BZOJ.1061.[NOI2008]志愿者招募(线性规划 对偶原理 单纯形 / 费用流SPFA)
- bzoj1061 [Noi2008]志愿者招募(费用流)
- bzoj1061【NOI2008】志愿者招募
- 【BZOJ 1061】 1061: [Noi2008]志愿者招募 (线性规划与网络流)**
- 【bzoj1061】[NOI2008]志愿者招募 线性规划与费用流
- [无源汇上下界最小费用可行流 差分费用流] BZOJ 1061 [Noi2008]志愿者招募
- [BZOJ1061]NOI2008志愿者招募|费用流|线性规划
- 【费用流|单纯形】BZOJ1061 [Noi2008]志愿者招募
- 【BZOJ 1061】 [Noi2008]志愿者招募
- [BZOJ1061]-[Noi2008]志愿者招募-线性规划+费用流
- BZOJ 1061 [Noi2008]志愿者招募 线性规划
- bzoj1061 [Noi2008]志愿者招募
- BZOJ 1061 Noi2008 志愿者招募 单纯形
- [BZOJ 1061][Noi2008]志愿者招募
- [BZOJ1061][Noi2008]志愿者招募
- [bzoj1061][NOI2008]志愿者招募
- [BZOJ1061][NOI2008]志愿者招募(费用流神题单纯形裸题)