zoj 3229 有源汇有上下界的最大流模板题
来源:互联网 发布:茶叶网络推广 编辑:程序博客网 时间:2024/04/30 12:19
/*坑啊,pe的程序在zoj上原来是wa。题目大意:一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝最多个C个女神拍照,每天拍照数不能超过D张,而且给每个女神i拍照有数量限制[Li,Ri],对于每个女神n天的拍照总和不能超过Gi,如果有解求屌丝最多能拍多少张照,并求每天给对应女神拍多少张照;否则输出-1。解题思路:增设一源点st,汇点sd,st到第i天连一条上界为Di下界为0的边,每个女神到汇点连一条下界为Gi上界为oo的边,对于每一天,当天到第i个女孩连一条[Li,Ri]的边。建图模型:源点s,终点d。超级源点ss,超级终点dd。首先判断是否存在满足所有边上下界的可行流,方法可以转化成无源汇有上下界的可行流问题。怎么转换呢?增设一条从d到s没有下界容量为无穷的边,那么原图就变成了一个无源汇的循环流图。接下来的事情一样,超级源点ss连i(du[i]>0),i连超级汇点(du[i]<0),对(ss,dd)进行一次最大流,当maxflow等于所有(du[]>0)之和时,有可行流,否则没有。当有可行流时,删除超级源点ss和超级终点dd,再对(s,d)进行一次最大流,此时得到的maxflow则为题目的解。为什么呢?因为第一次maxflow()只是求得所有满足下界的流量,而残留网络(s,d)路上还有许多自由流(没有和超级源点和超级汇点连接的边)没有流满,所有最终得到的maxflow=(第一次流满下界的流+第二次能流通的自由流)。*/#include<stdio.h>#include<string.h>#include<queue>using namespace std;#define N 1500#define ii 400000#define inf 0x3fffffffstruct node {int u,v,w,f,next;}bian[ii*2];int head[N],yong,dis[N],work[N];void init(){yong=0;memset(head,-1,sizeof(head));}void addbian(int u,int v,int w,int f) {bian[yong].u=u;bian[yong].v=v;bian[yong].w=w;bian[yong].f=f;bian[yong].next=head[u];head[u]=yong++;}void add(int u,int v,int w,int f) {addbian(u,v,w,f);addbian(v,u,0,f);}int min(int a,int b){ return a<b?a:b;}int bfs(int s,int t){ memset(dis,-1,sizeof(dis)); queue<int>q; q.push(s); dis[s]=0; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=bian[i].next) { int v=bian[i].v; if(bian[i].w&&dis[v]==-1) { dis[v]=dis[u]+1; q.push(v); if(v==t) return 1; } } } return 0;}int dfs(int s,int limit,int t){ if(s==t)return limit; for(int &i=work[s];i!=-1;i=bian[i].next) { int v=bian[i].v; if(bian[i].w&&dis[v]==dis[s]+1) { int tt=dfs(v,min(limit,bian[i].w),t); if(tt) { bian[i].w-=tt; bian[i^1].w+=tt; return tt; } } } return 0;}int dinic(int s,int t){ int ans=0; while(bfs(s,t)) { memcpy(work,head,sizeof(head)); while(int tt=dfs(s,inf,t)) ans+=tt; } return ans;}int main() { int n,m,i,j,k,s,t,S,T,a,b,d,index[ii],id,suma,w[N]; while(scanf("%d%d",&n,&m)!=EOF) { init(); s=0;t=m+n+1; S=t+1;T=S+1; memset(w,0,sizeof(w)); for(i=1;i<=m;i++) { scanf("%d",&a); w[t]+=a; w[i+n]-=a; add(i+n,t,inf-a,0); } id=0; for(i=1;i<=n;i++) { scanf("%d%d",&a,&b); add(s,i,b,b); while(a--) { scanf("%d%d%d",&j,&k,&d); j++; index[id++]=yong; w[i]-=k; w[j+n]+=k; add(i,j+n,d-k,d); } } add(t,s,inf,inf); suma=0; for(i=s;i<=t;i++) { if(w[i]>0) { suma+=w[i]; add(S,i,w[i],0); } else add(i,T,-w[i],0); } int f=dinic(S,T); if(f==suma) { head[S]=head[T]=-1; printf("%d\n",dinic(s,t)); for(i=0;i<id;i++) printf("%d\n",bian[index[i]].f-bian[index[i]].w); } else printf("-1\n"); printf("\n"); }return 0;}
0 0
- zoj 3229 有源汇有上下界的最大流模板题
- ZOJ 3229 有源有汇上下界最大流
- 【有源汇有上下界最大流】ZOJ-3229 Shoot the Bullet
- ZOJ 3229 Shoot the Bullet(有源汇有上下界的最大流)
- zoj 3229 Shoot the Bullet(有源汇有上下界的最大流)
- ZOJ 3229 Shoot the Bullet 有源汇有上下界的最大流
- zoj 3229 Shoot the Bullet (有源汇有上下界的最大流)
- 有源汇有上下界的最大流
- 有源汇上下界最大流 ZOJ 3229 代码
- ★ zoj 3229 有源汇上下界最大流
- zoj 3229 有源汇上下界最大流
- ZOJ - 3229 Shoot the Bullet(有源有汇上下界最大流)
- sgu 176 有源汇有上下界的最小流模板题
- ZOJ 3229 Shoot the Bullet 有源有汇带下界的最大流
- ZOJ 3229 Shoot the Bullet(有源汇有上下界最大流)
- bzoj3698 XWW的难题(有源汇有上下界最大流)
- loj116 有源汇有上下界最大流(如题)
- LOJ #116. 有源汇有上下界最大流
- leetcode 刷题报告 80 Single Number
- 基于canvas将图片转化成字符画
- 线段树 poj 2828 Buy Tickets
- Java多线程初学者指南:线程的生命周期
- ext3.x图标制作(饼图+柱状图)
- zoj 3229 有源汇有上下界的最大流模板题
- 【ThinkingInC++】13、输出移位运算符的操作
- 一道算法题引发的动态内存管理的思考
- CSS3详解:transform
- SGU 326. Perspective (最大流)
- 小米如何在社会化媒体上引爆口碑?
- 1176. Two Ends(搜索破解此题)
- LeetCode | Largest Rectangle in Histogram(直方图围城的最大矩形面积)
- 常用的八个CMD命令