最大流模板
2015-07-27 10:08
267 查看
#include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define For(a,b,c) for(int a = b;a <= c;a++) using namespace std; typedef long long ll; const int maxn = 1000005; const int INF = 0x3f3f3f3f; const int e_maxn = 1000 * 4; const int v_maxn = 500; struct ppp { int v,nex,cap,flow,c;//分别为下一个点,下一条边,当前边容量和流量,还有费用 }e[e_maxn]; int head[v_maxn],dis[v_maxn],cur[v_maxn];//链表头节点,层次图中每个点所属层次,dfs所用的临时链表头 int tole,N,M,s,t;//总加入边数,总输入点数和总输入边数,源点和汇点 void make_edge(int u,int v,int cap,int c)//求最大流时费用不必考虑,可以省去,加上也没关系 { e[tole].v = v;e[tole].flow = 0;e[tole].cap = cap;e[tole].c = c;e[tole].nex = head[u];head[u] = tole++; } void add_edge(int u,int v,int cap,int c) { make_edge(u,v,cap,c);//正向边容量为cap,费用为c make_edge(v,u,0,-c);//反向边容量为0,费用为-c } int bfs()//其中s为源点,t为汇点 { queue<int> que; que.push(s); mem(dis,-1); dis[s] = 0; int temp,v; while(!que.empty()) { temp = que.front(); que.pop(); for(int i = head[temp];~i;i = e[i].nex) { v = e[i].v; if(dis[v] == -1 && e[i].cap > e[i].flow) { dis[v] = dis[temp] + 1; que.push(v); } } } return dis[t] != -1; } int dfs(int x,int a) { if(x == t || !a) return a; int v,f,ret = 0; for(int &i = cur[x];~i;i = e[i].nex) { v = e[i].v; if((dis[v] == dis[x] + 1) && (f = dfs(v,min(a,e[i].cap - e[i].flow))) > 0) { e[i].flow += f; e[i ^ 1].flow -= f; a -= f; ret += f; if(!a)break; } } return ret; } void Dinic(int &ans)//ans为最大流 { while(bfs()) { for(int i = 0;i <= t;i++)cur[i] = head[i]; ans += dfs(s,INF); } }
相关文章推荐
- ASP.NET MVC异常处理
- ASP.NET POST XML JSON数据,发送与接收
- android/IOS各平台分享链接/跳转链接配置说明(备用)
- 2.16-switch
- android-async-http-master - 网络连接
- Reseachers
- Maven Unable to locate the Javac Compiler
- Android开发EditText属性详解
- 课堂笔记03
- 快搜搜:2015年应届生怎么找工作?
- atoi (String to Integer) leetcode
- 【转】windows c++获取文件信息——_stat函数的使用
- Google跨域配置
- 并查集详解(转)
- 机房收费之上机、结账分析
- Android模拟Http POST 请求
- Android中Activity间通信 -----intent & SharedPreferences
- 2.14-if的使用注意
- Android控件开发之EditView
- Android 控件开发之ToggleButton