强大的Dinic
来源:互联网 发布:承德县大数据招聘信息 编辑:程序博客网 时间:2024/06/04 22:19
Dinic算相对来讲比较稳定,写成邻接表示最好的选择
这里以hdu 4280 为例子 加入一个开栈的外挂神器
递归版:
struct EDGE
{
int v, w;
int next;
}E[maxn*2];
int head[maxn], level[maxn];
int k;
void addE(int u, int v,int w)
{
E[k].v = v;
E[k].w = w;
E[k].next = head[u];
head[u] = k++;
E[k].v = u;
E[k].w = w;
E[k].next = head[v];
head[v] = k++;
}
bool BFS(int s, int t)//层次网络的索搜和BSF索搜迷宫很像,因为都是一层一层的尽心,最终只要把层次记录就ok了
{
memset(level, 0, sizeof level);
Q<int>q;
q.push(s);
level[s] = 1;
while (!q.empty())
{
int u = q.front(); q.pop();
if (u == t)
return true;
for (int i = head[u]; i != -1; i = E[i].next)
{
int v = E[i].v;
if (!level[v] && E[i].w > 0)
{
level[v] = level[u] + 1;
q.push(v);
}
}
}
return false;
}
int DFS(int u,int maxf,int t)
{
int res = 0;
if (u == t)
return maxf;
for (int i = head[u]; i != -1; i = E[i].next)
{
int v = E[i].v;
if (level[v] == level[u] + 1 && E[i].w > 0)
{
int f = DFS(v, min(maxf - res, E[i].w), t);
E[i].w -= f;
E[i ^ 1].w += f;
res += f;
if (res == maxf)
return res;
}
}
if (res == 0)
level[u] = 0;
return res;
}
void Dinic(int s,int t)
{
int ans = 0;
while (BFS(s, t))
ans += DFS(s, INF_MAX, t);
printf("%d\n", ans);
}
非递归版:
struct Edge
{
int v, f;
int next;
}E[(maxn*2+maxm)*2];
int k;
int head[maxn], level[maxn], h[maxn], stack[maxn];
bool BFS(int s, int t)
{
memset(level, 0, sizeof level);
level[s] = 1;
Q<int>q;
q.push(s);
while (!q.empty())
{
int u = q.front(); q.pop();
if (u == t)
return true;
for (int i = head[u]; i != -1; i = E[i].next)
{
int v = E[i].v;
if (!level[v] && E[i].f>0)
{
level[v] = level[u] + 1;
q.push(v);
}
}
}
return false;
}
void Dinic(int s, int t)
{
int maxflow = 0;
while (BFS(s, t))
{
memcpy(h, head, sizeof h);
int top = 0, u = s;
while (true)
{
if (u == t)
{
int minflow = INF_MAX, flag;
for (int i = 0; i < top; i++)
{
if (minflow>E[stack[i]].f)
{
minflow = E[stack[i]].f;
flag = i;
}
}
for (int i = 0; i < top; i++)
{
E[stack[i]].f -= minflow;
E[stack[i] ^ 1].f += minflow;
}
top = flag;
maxflow += minflow;
u = E[stack[top]^1].v;//反向边的邻接点
}
for (int i = h[u]; i != -1; i = h[u] = E[i].next)
{
int v = E[i].v;
if (level[v] == level[u] + 1 && E[i].f)
break;
}
if (h[u] != -1)
{
stack[top++] = h[u];
u = E[h[u]].v;
}
else
{
if (top == 0)
break;
level[u] = 0;
u = E[stack[--top]^1].v;//反向边的邻接点
}
}
}
printf("%d\n", maxflow);
}
建议用非递归版的比较好,相对来讲性能会快些,而且在杭电不会爆栈式关键
这里以hdu 4280 为例子 加入一个开栈的外挂神器
递归版:
struct EDGE
{
int v, w;
int next;
}E[maxn*2];
int head[maxn], level[maxn];
int k;
void addE(int u, int v,int w)
{
E[k].v = v;
E[k].w = w;
E[k].next = head[u];
head[u] = k++;
E[k].v = u;
E[k].w = w;
E[k].next = head[v];
head[v] = k++;
}
bool BFS(int s, int t)//层次网络的索搜和BSF索搜迷宫很像,因为都是一层一层的尽心,最终只要把层次记录就ok了
{
memset(level, 0, sizeof level);
Q<int>q;
q.push(s);
level[s] = 1;
while (!q.empty())
{
int u = q.front(); q.pop();
if (u == t)
return true;
for (int i = head[u]; i != -1; i = E[i].next)
{
int v = E[i].v;
if (!level[v] && E[i].w > 0)
{
level[v] = level[u] + 1;
q.push(v);
}
}
}
return false;
}
int DFS(int u,int maxf,int t)
{
int res = 0;
if (u == t)
return maxf;
for (int i = head[u]; i != -1; i = E[i].next)
{
int v = E[i].v;
if (level[v] == level[u] + 1 && E[i].w > 0)
{
int f = DFS(v, min(maxf - res, E[i].w), t);
E[i].w -= f;
E[i ^ 1].w += f;
res += f;
if (res == maxf)
return res;
}
}
if (res == 0)
level[u] = 0;
return res;
}
void Dinic(int s,int t)
{
int ans = 0;
while (BFS(s, t))
ans += DFS(s, INF_MAX, t);
printf("%d\n", ans);
}
非递归版:
struct Edge
{
int v, f;
int next;
}E[(maxn*2+maxm)*2];
int k;
int head[maxn], level[maxn], h[maxn], stack[maxn];
bool BFS(int s, int t)
{
memset(level, 0, sizeof level);
level[s] = 1;
Q<int>q;
q.push(s);
while (!q.empty())
{
int u = q.front(); q.pop();
if (u == t)
return true;
for (int i = head[u]; i != -1; i = E[i].next)
{
int v = E[i].v;
if (!level[v] && E[i].f>0)
{
level[v] = level[u] + 1;
q.push(v);
}
}
}
return false;
}
void Dinic(int s, int t)
{
int maxflow = 0;
while (BFS(s, t))
{
memcpy(h, head, sizeof h);
int top = 0, u = s;
while (true)
{
if (u == t)
{
int minflow = INF_MAX, flag;
for (int i = 0; i < top; i++)
{
if (minflow>E[stack[i]].f)
{
minflow = E[stack[i]].f;
flag = i;
}
}
for (int i = 0; i < top; i++)
{
E[stack[i]].f -= minflow;
E[stack[i] ^ 1].f += minflow;
}
top = flag;
maxflow += minflow;
u = E[stack[top]^1].v;//反向边的邻接点
}
for (int i = h[u]; i != -1; i = h[u] = E[i].next)
{
int v = E[i].v;
if (level[v] == level[u] + 1 && E[i].f)
break;
}
if (h[u] != -1)
{
stack[top++] = h[u];
u = E[h[u]].v;
}
else
{
if (top == 0)
break;
level[u] = 0;
u = E[stack[--top]^1].v;//反向边的邻接点
}
}
}
printf("%d\n", maxflow);
}
建议用非递归版的比较好,相对来讲性能会快些,而且在杭电不会爆栈式关键
0 0
- 强大的Dinic
- dinic算法的改进
- dinic
- dinic
- Dinic
- Dinic
- dinic
- Dinic
- dinic
- Dinic
- dinic
- dinic
- Dinic
- dinic
- Dinic
- 白书上的Dinic模板
- Dinic算法的程序实现
- 最大流的Dinic算法
- CocoaPods 的概述 安装和基本用法
- cocos2d clippindNode,新手引导
- u-boot中分区和内核MTD分区关系
- 2014 MVP Open Day 见闻(中)
- pydev插件安装方法
- 强大的Dinic
- python ez_setup.py 安装
- 2014 MVP Open Day 见闻(下)
- 进程间传递socket的做法
- 弹出窗口与父窗口交互
- 数据分析这点事
- 学习较底层编程:动手写一个C语言编译器
- Microsoft Office Word 2007 文档结构图突然变小的解决办法
- linux下ipcs和ipcrm命令详解