您的位置:首页 > 其它

最大流模板

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: