bzoj1497: [NOI2006]最大获利 DINIC
2014-11-25 12:52
267 查看
【建模方法】
注意到题目中加粗的两个字“必须”,此题是典型的“蕴含式最大获利问题”,套用解决最大权闭合子图的建模方法即可解决。每个项目i作为一个点并连边(s, i, Ai),每名员工j作为一个点并连边(j, t, Bj),若项目i需要雇用员工j则连边(i, j, ∞)。设最小割为ans,那么ΣAi-ans即为结果。
注意到题目中加粗的两个字“必须”,此题是典型的“蕴含式最大获利问题”,套用解决最大权闭合子图的建模方法即可解决。每个项目i作为一个点并连边(s, i, Ai),每名员工j作为一个点并连边(j, t, Bj),若项目i需要雇用员工j则连边(i, j, ∞)。设最小割为ans,那么ΣAi-ans即为结果。
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #define INF 0x3fffffff using namespace std; #define maxn 444444 #define INF 0x3fffffff struct node { int next,c,v; }e[maxn]; int en,ed,st,q[maxn],n,m; int dis[maxn],first[maxn],cur[maxn]; int save[maxn],save2[maxn]; bool bfs() { memset(dis,-1,sizeof(dis)); dis[st]=0; int tail,head; tail=head=1; tail++; q[tail]=st; int v,u; while(head<tail) { head++; u=q[head]; for(int i=first[u];i!=-1;i=e[i].next) { v=e[i].v; if(dis[v]!=-1) continue; if(e[i].c==0) continue; dis[v]=dis[u]+1; tail++; q[tail]=v; if(v==ed) return true; } } return false; } int dfs(int x,int mx) { if(x==ed||mx==0) return mx; int f,flow=0,v,ret=0; for(int& i=cur[x];i!=-1;i=e[i].next) { v=e[i].v; if(dis[x]+1!=dis[v]) continue; if((f=dfs(v,min(mx,e[i].c)))) { e[i].c-=f; e[i^1].c+=f; flow+=f; ret+=f; mx-=f; if(!mx) break; } } if(ret==0) dis[x]=-1; return flow; } int dinic() { int tmp=0,maxflow=0; while(bfs()) { for(int i=1;i<=ed;i++) cur[i]=first[i]; while(tmp=dfs(st,INF)) maxflow+=tmp; } return maxflow; } void add(int a,int b,int c) { e[en].v=b; e[en].next=first[a]; e[en].c=c; first[a]=en; en++; e[en].v=a; e[en].next=first[b]; e[en].c=0; first[b]=en; en++; } void build() { int sum=0; for(int i=1;i<=n;i++) { scanf("%d",&save[i]); add(i,ed,save[i]); } int a,b,c; for(int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); sum+=c; add(i+n,a,INF); add(i+n,b,INF); add(st,i+n,c); } printf("%d\n",sum-dinic()); } void init() { memset(first,-1,sizeof(first)); en=0; st=n+m+1; ed=st+1; } int main() { scanf("%d%d",&n,&m); init(); build(); return 0; }
相关文章推荐
- 【Dinic】bzoj1497 noi2006 最大获利
- 【NOI2006】BZOJ1497最大获利
- bzoj 1497: [NOI2006]最大获利 -- 最小割
- bzoj1497【NOI2006】最大获利
- bzoj1497: [NOI2006]最大获利
- 【BZOJ1497】【NOI2006】最大获利
- [bzoj1497]NOI2006最大获利(最大权封闭子图)
- BZOJ_1497_[NOI2006]_最大获利_(最大流+最大权闭合图)
- [BZOJ1497][NOI2006]最大获利(最小割)
- BZOJ 1497 [NOI2006]最大获利 【最大流】
- [BZOJ1497][NOI2006]最大获利
- [NOI2006]最大获利 BZOJ1497 - 最小割
- bzoj1497 [NOI2006]最大获利
- [最小割]BZOJ 1497——[NOI2006]最大获利
- BZOJ 1497: [NOI2006]最大获利 最大权闭合子图
- 【bzoj1497】[NOI2006]最大获利 最大点权闭合图
- BZOJ 1497 [NOI2006]最大获利
- BZOJ 1497: [NOI2006]最大获利
- 【BZOJ】1497: [NOI2006]最大获利 最大权闭合子图或最小割
- bzoj1497【NOI2006】最大获利