bzoj 1497: [NOI2006]最大获利
2016-03-13 06:35
302 查看
#include<cstdio> #include<iostream> #include<cstring> #define M 100008 #define inf 2139062143 using namespace std; int T,head[M],next[10*M],u[10*M],v[10*M],d[M],n,m,cnt=1,ans,q[2*M],sum; void jia(int a1,int a2,int a3) { cnt++; u[cnt]=a2; v[cnt]=a3; next[cnt]=head[a1]; head[a1]=cnt; } bool bfs() { memset(d,0,sizeof(int)*(T+2)); int h=0,t=1; q[1]=0; d[0]=1; for(;h<t;) { h++; int p=q[h]; for(int i=head[p];i;i=next[i]) if(!d[u[i]]&&v[i]) { d[u[i]]=d[p]+1; if(d[T]) return 1; t++; q[t]=u[i]; } } return 0; } int dinic(int s,int f) { if(s==T) return f; int rest=f; for(int i=head[s];i&&rest;i=next[i]) if(v[i]&&d[u[i]]==d[s]+1) { int now=dinic(u[i],min(rest,v[i])); if(!now) d[u[i]]=0; v[i]-=now; v[i^1]+=now; rest-=now; } return f-rest; } int main() { scanf("%d%d",&n,&m); T=n+m+1; for(int i=1;i<=n;i++) { int a1; scanf("%d",&a1); jia(i,T,a1); jia(T,i,0); } for(int i=1;i<=m;i++) { int a1,a2,a3,a4; a3=n+i; scanf("%d%d%d",&a1,&a2,&a4); sum+=a4; jia(a3,a1,inf); jia(a1,a3,0); jia(a3,a2,inf); jia(a2,a3,0); jia(0,a3,a4); jia(a3,0,0); } for(;bfs();) ans+=dinic(0,inf); printf("%d\n",sum-ans); return 0; }
最小割 站向汇点连容量为费用的边,源点向用户群连容量为获利的边,用户群与站之间有关联的连容量为inf的边,跑最小割,用总收益减去即为答案。
相关文章推荐
- 第一次
- Eclipse快捷键
- bzoj 1492: [NOI2007]货币兑换Cash
- bzoj 1491: [NOI2007]社交网络
- 71.双向最短路径:聚会
- bzoj 1483: [HNOI2009]梦幻布丁
- 71.双向最短路径:聚会
- 71.双向最短路径:聚会
- [leetcode] 245. Shortest Word Distance III 解题报告
- bzoj 1433: [ZJOI2009]假期的宿舍
- bzoj 1432: [ZJOI2009]Function
- bzoj 1415: [Noi2005]聪聪和可可
- bzoj 1412: [ZJOI2009]狼和羊的故事
- Palindrome 系列
- 谷歌人机大战与新时代的来临
- 工厂模式之小结与区别(6)
- 抽象工厂模式(5)
- 抽象工厂模式(4)
- leetcode@ [116/117] Populating Next Right Pointers in Each Node I & II (Tree, BFS)
- !getApplicationContext()和Activity.this区别