bzoj 1391 [Ceoi2008]order(最小割)
2016-03-22 11:55
316 查看
【题意】
有n个有偿工作选做,m个机器,完成一个工作需要若干个工序,完成每个工序需要一个机器,对于一个机器,在不同的工序有不同的租费,但买下来的费用只有一个。问最大获益。
【思路】
对于工作和机器建点,由S向每一个工作连边(S,u,a)a为完成工作的奖励,由一个工作向所需机器连边(u,v,b)b为租用机器费用,由每个机器向T连边(v,T,c)c为购买机器的费用。
求最小割,构图提供的选择有:不做该工作,租用一个工序需要的机器,购买一个机器满足所有需要。最小割保证ST不相连,即保证给所有工作分配了一种方案:完成所有工序或不做该工作,且该方案花费最少,最小割即为最小亏损。
【代码】
有n个有偿工作选做,m个机器,完成一个工作需要若干个工序,完成每个工序需要一个机器,对于一个机器,在不同的工序有不同的租费,但买下来的费用只有一个。问最大获益。
【思路】
对于工作和机器建点,由S向每一个工作连边(S,u,a)a为完成工作的奖励,由一个工作向所需机器连边(u,v,b)b为租用机器费用,由每个机器向T连边(v,T,c)c为购买机器的费用。
求最小割,构图提供的选择有:不做该工作,租用一个工序需要的机器,购买一个机器满足所有需要。最小割保证ST不相连,即保证给所有工作分配了一种方案:完成所有工序或不做该工作,且该方案花费最少,最小割即为最小亏损。
【代码】
#include<set> #include<cmath> #include<queue> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define trav(u,i) for(int i=front[u];i;i=e[i].nxt) #define FOR(a,b,c) for(int a=(b);a<=(c);a++) using namespace std; typedef long long ll; const int N = 4e3+10; const int inf = 1e9; ll read() { char c=getchar(); ll f=1,x=0; while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x*f; } struct Edge { int u,v,cap,flow; }; struct Dinic { int n,m,s,t; int d ,cur ,vis ; vector<int> g ; vector<Edge> es; queue<int> q; void init(int n) { this->n=n; es.clear(); FOR(i,0,n) g[i].clear(); } void AddEdge(int u,int v,int w) { es.push_back((Edge){u,v,w,0}); es.push_back((Edge){v,u,0,0}); m=es.size(); g[u].push_back(m-2); g[v].push_back(m-1); } int bfs() { memset(vis,0,sizeof(vis)); q.push(s); d[s]=0; vis[s]=1; while(!q.empty()) { int u=q.front(); q.pop(); FOR(i,0,(int)g[u].size()-1) { Edge& e=es[g[u][i]]; int v=e.v; if(!vis[v]&&e.cap>e.flow) { vis[v]=1; d[v]=d[u]+1; q.push(v); } } } return vis[t]; } int dfs(int u,int a) { if(u==t||!a) return a; int flow=0,f; for(int& i=cur[u];i<g[u].size();i++) { Edge& e=es[g[u][i]]; int v=e.v; if(d[v]==d[u]+1&&(f=dfs(v,min(a,e.cap-e.flow)))>0) { e.flow+=f; es[g[u][i]^1].flow-=f; flow+=f; a-=f; if(!a) break; } } return flow; } int MaxFlow(int s,int t) { this->s=s,this->t=t; int flow=0; while(bfs()) { memset(cur,0,sizeof(cur)); flow+=dfs(s,inf); } return flow; } } dc; int n,m,S,T; int main() { n=read(),m=read(); dc.init(n+m+2); int S=0,T=n+m+1; int ans=0; FOR(i,1,n) { int a=read(),b=read(); ans+=a; dc.AddEdge(S,i,a); FOR(j,1,b) { int x=read(),y=read(); dc.AddEdge(i,x+n,y); } } FOR(i,1,m) { int x=read(); dc.AddEdge(n+i,T,x); } printf("%d",ans-dc.MaxFlow(S,T)); return 0; }
相关文章推荐
- PLSQL Developer如何连接远程Oracle数据库
- ArcMenu扇形菜单(底部)
- 国内UED收录
- webview加载网页与全屏播放视频?
- js导入外部脚本文件
- js 格式化显示时间方法
- pure-ftpd搭建教程
- 蓝桥杯 入门训练 序列求和
- 服务性能监控都包括哪些指标?
- CGAffineTransform相关函数
- webservice 超时设置
- 事件阻止
- YII2 basic版文件夹描述及应用启动流程
- [问题] 分类模型泛化能力不好
- jQuery插件开发
- zenoss安装配置
- 需求 - 20 - 提示框
- 蓝桥杯 入门训练 A+B问题
- Windows10如何利用fiddler抓去Android手机应用的包
- MySQL分库分表环境下全局ID生成方案