ZOJ3229 Shoot the Bullet(有源汇流量有上下界网络的最大流)
2016-04-10 15:58
633 查看
题目大概说在n天里给m个女孩拍照,每个女孩至少要拍Gi张照片,每一天最多拍Dk张相片且都有Ck个拍照目标,每一个目标拍照的张数要在[Lki, Rki]范围内,问最多能拍几张照片。
源点-天-女孩-汇点,这样子建容量网络。然后就是求这个有源汇流量有上下界容量网络的最大流:
首先计算其可行流,POJ2396
然后删除附加源、附加汇以及汇点到源点容量INF的边
最后从源点到汇点跑一边最大流即可
源点-天-女孩-汇点,这样子建容量网络。然后就是求这个有源汇流量有上下界容量网络的最大流:
首先计算其可行流,POJ2396
然后删除附加源、附加汇以及汇点到源点容量INF的边
最后从源点到汇点跑一边最大流即可
#include<cstdio> #include<cstring> #include<vector> #include<queue> #include<algorithm> using namespace std; #define INF (1<<30) #define MAXN 2222 #define MAXM 444*2222 struct Edge{ int v,cap,flow,next; }edge[MAXM]; int vs,vt,NE,NV; int head[MAXN]; void addEdge(int u,int v,int cap){ edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0; edge[NE].next=head[u]; head[u]=NE++; edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0; edge[NE].next=head[v]; head[v]=NE++; } int level[MAXN]; int gap[MAXN]; void bfs(){ memset(level,-1,sizeof(level)); memset(gap,0,sizeof(gap)); level[vt]=0; gap[level[vt]]++; queue<int> que; que.push(vt); while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(level[v]!=-1) continue; level[v]=level[u]+1; gap[level[v]]++; que.push(v); } } } int pre[MAXN]; int cur[MAXN]; int ISAP(){ bfs(); memset(pre,-1,sizeof(pre)); memcpy(cur,head,sizeof(head)); int u=pre[vs]=vs,flow=0,aug=INF; gap[0]=NV; while(level[vs]<NV){ bool flag=false; for(int &i=cur[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){ flag=true; pre[v]=u; u=v; //aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap)); aug=min(aug,edge[i].cap-edge[i].flow); if(v==vt){ flow+=aug; for(u=pre[v]; v!=vs; v=u,u=pre[u]){ edge[cur[u]].flow+=aug; edge[cur[u]^1].flow-=aug; } //aug=-1; aug=INF; } break; } } if(flag) continue; int minlevel=NV; for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(edge[i].cap!=edge[i].flow && level[v]<minlevel){ minlevel=level[v]; cur[u]=i; } } if(--gap[level[u]]==0) break; level[u]=minlevel+1; gap[level[u]]++; u=pre[u]; } return flow; } int d[MAXN],low[366][1111]; int main(){ int n,m,a,b,c,l,r; while(~scanf("%d%d",&n,&m)){ memset(d,0,sizeof(d)); int S=0,T=n+m+1; vs=T+1; vt=vs+1; NV=vt+1; NE=0; memset(head,-1,sizeof(head)); for(int i=1; i<=m; ++i){ scanf("%d",&a); addEdge(i+n,T,INF); d[T]-=a; d[i+n]+=a; } memset(low,0,sizeof(low)); vector<int> target[366]; for(int i=1; i<=n; ++i){ scanf("%d%d",&c,&a); addEdge(S,i,a); while(c--){ scanf("%d%d%d",&a,&l,&r); ++a; target[i].push_back(a); low[i][a]=l; addEdge(i,a+n,r-l); d[a+n]-=l; d[i]+=l; } } int tag=NE; addEdge(T,S,INF); int tot=0; for(int i=S; i<=T; ++i){ if(d[i]<0) addEdge(vs,i,-d[i]); else addEdge(i,vt,d[i]),tot+=d[i]; } tagEnd: if(ISAP()!=tot){ puts("-1\n"); continue; } for(int i=tag; i<NE; ++i){ edge[i].cap=edge[i].flow=0; } vs=S; vt=T; ISAP(); tot=0; for(int i=head[vs]; i!=-1; i=edge[i].next){ if(i&1) continue; tot+=edge[i].flow; } printf("%d\n",tot); for(int u=1; u<=n; ++u){ for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v-n; if(i&1 || v<1 || v>m) continue; low[u][v]+=edge[i].flow; } } for(int u=1; u<=n; ++u){ for(int i=0; i!=target[u].size(); ++i){ printf("%d\n",low[u][target[u][i]]); } } putchar('\n'); } return 0; }
相关文章推荐
- RTSP协议、RTMP协议、HTTP协议的区别
- 三大WEB服务器对比分析(apache ,lighttpd,nginx)
- 详解网络流量监控
- TCP/IP卷一(第二章学习)
- 详解网络流量监控
- HTTP请求方法
- java 多线程下载文件 以及URLConnection和HttpURLConnection的区别
- Android 使用OKhttp 3.0以上版本上传文件或图片(MultipartBuilder已不可用)
- whu 1603 Minimum Sum(16武汉邀请赛网络赛)
- TCP/IP卷一(第一章学习)
- [转]TCP的拥塞控制
- 服务器基于workerman,客户端基于ODSocket的TCP,socket通信,本地测试
- 从零开始用python实现神经网络
- 高性能网络服务器编程:为什么linux下epoll是最好,Netty要比NIO.2好?
- javaweb学习总结(十)——HttpServletRequest对象(一)
- 简析TCP的三次握手与四次分手
- 20159217《网络攻防实践》第六周学习总结
- 解读HTTP与HTTPS的区别
- 深度信念网络Deep Belief Networks资料汇总
- Android中Http请求