【费用流】[BZOJ1061]/[HYSBZ1061]志愿者招募
来源:互联网 发布:淘宝买lol账号流程 编辑:程序博客网 时间:2024/05/25 08:15
题目
分析:建图的方法还是比较难想。
首先,计算两个相邻时刻的差分,若a[i] < a[i-1],就从i向汇点连边,容量为a[i-1]-a[i],若a[i] > a[i-1],就从源点向i连边,容量为a[i]-a[i-1]
请联系差分数组理解。
然后,对于志愿者,连s->(t+1),容量为+∞,费用为c。
最后,由于志愿者可以多不能少,连(i+1)->i,容量为+∞。
跑费用流算出费用即可。
#include<cstdio>#include<algorithm>#include<cstring>#include<queue>#define MAXN 1000#define MAXM 10000#define INF 0x7f7f7f7f7f7f7f7fllusing namespace std;deque<int>q;void Read(int &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return; }}int n,m,S,T,a[MAXN+10];typedef long long LL;LL dist[MAXN+10],cost;bool vis[MAXN+10];struct node{ int wt,v; LL cap; node *next,*back;}*adj[MAXN+10],edge[MAXN*4+MAXM*2+10],*ecnt=edge,*pre[MAXN+10];template<class T>void Read(T &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return; }}void addedge(int u,int v,int wt,LL cap){ node *p=++ecnt; p->v=v; p->wt=wt; p->cap=cap; p->next=adj[u]; adj[u]=p; p=p->back=++ecnt; p->v=u; p->wt=-wt; p->cap=0; p->next=adj[v]; adj[v]=p; p->back=ecnt-1;}void read(){ Read(n),Read(m); int i,s,t,c; T=n+2; for(i=1;i<=n;i++) Read(a[i]); for(i=1;i<=n;i++){ if(a[i]>a[i-1]) addedge(S,i,0,a[i]-a[i-1]); else if(a[i]<a[i-1]) addedge(i,T,0,a[i-1]-a[i]); addedge(i+1,i,0,INF); } addedge(n+1,T,0,a[n]); for(i=1;i<=m;i++){ Read(s),Read(t),Read(c); addedge(s,t+1,c,INF); }}bool spfa(){ memset(dist,0x7f,sizeof dist); memset(pre,0,sizeof pre); q.push_back(S); vis[S]=1; dist[S]=0; int u,v,len; LL sum; while(!q.empty()){ u=q.front(); q.pop_front(); if(dist[u]*len>sum){ q.push_back(u); continue; } len--; sum-=dist[u]; vis[u]=0; for(node *p=adj[u];p;p=p->next){ v=p->v; if(p->cap>0&&dist[v]>dist[u]+p->wt){ dist[v]=dist[u]+p->wt; pre[v]=p; if(!vis[v]){ vis[v]=1; if(q.empty()||dist[v]>dist[q.front()]) q.push_back(v); else q.push_front(v); sum+=dist[v]; len++; } } } } if(dist[T]==INF) return 0; return 1;}void mcmf(){ int u; LL delta; while(spfa()){ delta=INF; for(u=T;u!=S;u=pre[u]->back->v) delta=min(delta,pre[u]->cap); for(u=T;u!=S;u=pre[u]->back->v){ pre[u]->cap-=delta; pre[u]->back->cap+=delta; cost+=delta*pre[u]->wt; } }}int main(){ read(); mcmf(); printf("%lld\n",cost);}
0 0
- 【费用流】[BZOJ1061]/[HYSBZ1061]志愿者招募
- bzoj1061: [Noi2008]志愿者招募 费用流
- [BZOJ1061]NOI2008志愿者招募|费用流|线性规划
- [BZOJ1061][NOI2008]志愿者招募 费用流
- bzoj1061志愿者招募 费用流or单纯形
- 【BZOJ1061】【codevs1803】志愿者招募,神奇建图费用流
- [BZOJ1061] [NOI2008] 志愿者招募 - 最小费用最大流
- 【费用流|单纯形】BZOJ1061 [Noi2008]志愿者招募
- [线性规划 费用流]BZOJ1061 志愿者招募 && BZOJ3112防守战线
- bzoj1061: [Noi2008]志愿者招募(最小费用最大流)
- bzoj1061 [Noi2008]志愿者招募(线性规划/费用流)
- 【BZOJ1061】【NOI2008】志愿者招募 费用流神题、单纯形裸题(代码费用流)
- [BZOJ1061][Noi2008]志愿者招募
- bzoj1061【NOI2008】志愿者招募
- 【NOI2008】【BZOJ1061】志愿者招募
- bzoj1061: [Noi2008]志愿者招募
- 【NOI2008】BZOJ1061志愿者招募
- [bzoj1061][NOI2008]志愿者招募
- 自定义类型转换器
- 畅通工程续floyd
- java异常
- [Python标准库]functools——管理函数的工具
- Qt多线程学习:创建多线程
- 【费用流】[BZOJ1061]/[HYSBZ1061]志愿者招募
- Win7+虚拟机OS X 10.8.5+Xcode4.6.3+越狱iPhone4+iOS5.1.1真机调试及生成ipa包
- js跨域
- 正则表达式
- “HINSTANCE ShellExecuteW(HWND,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,INT)”
- 成功的背后!(给所有IT人)
- 贝叶斯分析——从数值积分到MCMC
- qt线程(转)----这篇很专业!
- 阿里云ECS服务器的使用