题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3549
题目大意:题目就是告诉你点和边的数量n和m,然后就是每条边连接的两个点和值,要你求出从1到n的最大流
递归版:
#include <cstdio>
#include <queue>
#include <cstring>
#include <vector>
using namespace std;
const int maxv = 20;
const long long INF = 0x3f3f3f;
struct Edge
{
int from, to, cap, flow;
Edge() {}
Edge(int from, int to, int cap, int flow)
{
this->from = from;
this->to = to;
this->cap = cap;
this->flow = flow;
}
};
struct Dinic
{
int n, m, s, t;
vector<Edge> edges;
vector<int> G[maxv];
bool vis[maxv];
int d[maxv];
int cur[maxv];
void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge(from, to, cap, 0));
edges.push_back(Edge(to, from, 0, 0));
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BFS()
{
memset(vis, 0, sizeof(vis));
queue<int>Q;
Q.push(s);
d[s] = 0;
vis[s] = 1;
while (!Q.empty())
{
int x = Q.front();
Q.pop();
for (int i = 0; i < (int)G[x].size(); i++)
{
Edge& e = edges[G[x][i]];
if (!vis[e.to] && e.cap > e.flow)
{
vis[e.to] = 1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x, int a)
{
if (x == t || a == 0) return a;
int flow = 0, f;
for (int& i = cur[x]; i < (int)G[x].size(); i++)
{
Edge& e = edges[G[x][i]];
if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0)
{
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if (a == 0) break;
}
}
return flow;
}
int Maxflow(int s, int t)
{
this -> s = s;
this -> t = t;
int flow = 0;
while (BFS())
{
memset(cur, 0, sizeof(cur));
flow += DFS(s, INF);
}
return flow;
}
};
int main()
{
int n, m, u, v, c, i, t;
scanf("%d", &t);
for (int ii = 1; ii <= t; ii++)
{
Dinic H;
scanf("%d%d", &n, &m);
for(i=1; i<=m; ++i)
{
scanf("%d%d%d", &u, &v, &c);
H.AddEdge(u, v, c);
}
printf("Case %d: %d\n", ii, H.Maxflow(1, n));
}
return 0;
}
非递归版:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 405;
const int maxm = maxn * maxn;
const int inf = 1000000000;
class Dinic
{
public :
struct Node
{
int u, v, f, next;
} e[maxm];
int head[maxn], p, lev[maxn], cur[maxn];
int que[maxm];
void init()
{
p = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int f)
{
e[p].u = u;
e[p].v = v;
e[p].f = f;
e[p].next = head[u];
head[u] = p++;
e[p].u = v;
e[p].v = u;
e[p].f = 0;
e[p].next = head[v];
head[v] = p++;
}
bool bfs(int s, int t)
{
int u, v, qin = 0, qout = 0;
memset(lev, 0, sizeof(lev));
lev[s] = 1;
que[qin++] = s;
while(qout != qin)
{
u = que[qout++];
for(int i = head[u]; i != -1; i = e[i].next)
{
if(e[i].f > 0 && !lev[v = e[i].v])
{
lev[v] = lev[u] + 1, que[qin++] = v;
if(v == t) return 1;
}
}
}
return 0;
}
int dfs(int s, int t)
{
int i, f, qin, u, k;
int flow = 0;
while(bfs(s, t))
{
memcpy(cur, head, sizeof(head));
u = s, qin = 0;
while(1)
{
if(u == t)
{
for(k = 0, f = inf; k < qin; k++)
if(e[que[k]].f < f) f = e[que[i=k]].f;
for(k = 0; k < qin; k++)
e[que[k]].f -= f, e[que[k]^1].f += f;
flow += f, u = e[que[qin = i]].u;
}
for(i = cur[u]; cur[u] != -1; i = cur[u] = e[cur[u]].next)
if(e[i].f > 0 && lev[u] + 1 == lev[e[i].v]) break;
if(cur[u] != -1)
que[qin++] = cur[u], u = e[cur[u]].v;
else
{
if(qin == 0) break;
lev[u] = -1, u = e[que[--qin]].u;
}
}
}
return flow;
}
} H;
int main()
{
int n, m, u, v, c, i, t;
scanf("%d", &t);
for (int ii = 1; ii <= t; ii++)
{
H.init();
scanf("%d%d", &n, &m);
for(i=1; i<=m; ++i)
{
scanf("%d%d%d", &u, &v, &c);
H.add(u, v, c);
}
printf("Case %d: %d\n", ii, H.dfs(1, n));
}
return 0;
}