[BZOJ1834][ZJOI2010]network 网络扩容(最大流+费用流)
2016-04-28 15:13
561 查看
题目描述
传送门题解
Q1 傻逼最大流Q2 求出最大流之后将图暴力重构,原图中的边费用为0,流量为初始流量,添加一些和原图边同始同终的边,费用为扩容费用,流量为INF,再添加一个超级源连向原先的源点,费用为0,流量为k+maxflow来限流,求最小费用流即可。
思路如此简单我这个傻逼刚开始想错了,,,Orz ATP
代码
#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; const int max_n=1e3+5; const int max_m=5e4+5; const int max_e=max_m*2; const int INF=1e9; int n,m,k,cap,maxflow,mincost; int tot,point[max_n],next[max_e],v[max_e],remain[max_e],c[max_e]; int deep[max_n],cur[max_n],last[max_n],num[max_n],dis[max_n]; bool vis[max_n]; struct hp{int x,y,cap,w;}edge[max_m]; queue <int> q; inline void addedge(int x,int y,int cap,int z){ ++tot; next[tot]=point[x]; point[x]=tot; v[tot]=y; remain[tot]=cap; c[tot]=z; ++tot; next[tot]=point[y]; point[y]=tot; v[tot]=x; remain[tot]=0; c[tot]=-z; } inline void bfs(int t){ for (int i=1;i<=n;++i) deep[i]=n; deep[t]=0; while (!q.empty()) q.pop(); q.push(t); while (!q.empty()){ int now=q.front(); q.pop(); for (int i=point[now];i!=-1;i=next[i]) if (deep[v[i]]==n&&remain[i^1]){ deep[v[i]]=deep[now]+1; q.push(v[i]); } } } inline int addflow(int s,int t){ int now=t,ans=INF; while (now!=s){ ans=min(ans,remain[last[now]]); now=v[last[now]^1]; } now=t; while (now!=s){ remain[last[now]]-=ans; remain[last[now]^1]+=ans; now=v[last[now]^1]; } return ans; } inline void isap(int s,int t){ bfs(t); for (int i=1;i<=n;++i) ++num[deep[i]]; for (int i=1;i<=n;++i) cur[i]=point[i]; int now=s; while (deep[s]<n){ if (now==t){ maxflow+=addflow(s,t); now=s; } bool has_find=false; for (int i=cur[now];i!=-1;i=next[i]) if (deep[v[i]]+1==deep[now]&&remain[i]){ has_find=true; cur[now]=i; last[v[i]]=i; now=v[i]; break; } if (!has_find){ int minn=n-1; for (int i=point[now];i!=-1;i=next[i]) if (remain[i]) minn=min(minn,deep[v[i]]); if (!(--num[deep[now]])) break; num[deep[now]=minn+1]++; cur[now]=point[now]; if (now!=s) now=v[last[now]^1]; } } } inline bool bfs(int s,int t){ memset(dis,0x7f,sizeof(dis)); dis[n+1]=0; memset(vis,0,sizeof(vis)); vis[n+1]=true; while (!q.empty()) q.pop(); q.push(n+1); while (!q.empty()){ int now=q.front(); q.pop(); vis[now]=false; for (int i=point[now];i!=-1;i=next[i]) if (dis[v[i]]>dis[now]+c[i]&&remain[i]){ dis[v[i]]=dis[now]+c[i]; last[v[i]]=i; if (!vis[v[i]]){ vis[v[i]]=true; q.push(v[i]); } } } if (dis[t]>INF) return false; int flow=addflow(s,t); mincost+=dis[t]*flow; return true; } inline void min_cost_flow(int s,int t){ mincost=0; while (bfs(s,t)); } inline void rebuild(){ tot=-1; memset(point,-1,sizeof(point)); memset(next,-1,sizeof(next)); for (int i=1;i<=m;++i){ addedge(edge[i].x,edge[i].y,edge[i].cap,0); addedge(edge[i].x,edge[i].y,INF,edge[i].w); } addedge(n+1,1,maxflow+k,0); min_cost_flow(n+1,n); } int main(){ scanf("%d%d%d",&n,&m,&k); tot=-1; memset(next,-1,sizeof(next)); memset(point,-1,sizeof(point)); for (int i=1;i<=m;++i){ scanf("%d%d%d%d",&edge[i].x,&edge[i].y,&edge[i].cap,&edge[i].w); addedge(edge[i].x,edge[i].y,edge[i].cap,0); } isap(1,n); printf("%d ",maxflow); rebuild(); printf("%d\n",mincost); }
相关文章推荐
- 《图解TCP/IP》读书笔记(1)
- 高性能数据序列化库,可序列化为binary,也可序列化为json,支持C++ java python php objectc 语言,兼容json数据格试,可以互相转换,跨语言交换数据,网络传输,远程调
- CentOS 7 虚拟机搭建lamp (php-fpm),三者分离,https认证
- python urllib2 发起http请求post
- Android网络请求心路历程
- 12、Http协议入门
- iOS开发网络篇—HTTP协议
- iOS开发网络篇—发送json数据给服务器以及多值参数
- Unix网络编程:master进程+work进程架构
- 使用CORS 实现Ajax的另类跨域
- curl 模拟http
- 今天练习了一下HTTP操作
- TCP拥塞控制机制
- 网络字节序与主机字节序
- http和https区别
- 在libevent事件基础上实现一个TCPServer类
- XMLHttpRequest
- android下载网络图片并缓存
- http://guhanjie.iteye.com/blog/1683637
- linux配置oracle11G监听及本地网络服务 及 数据库建库