裸版:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int MAX_NODE_NUM = 100;
const int MAX_EDGE_NUM = 5000;
struct Edge {
int to;
int flow;
int next;
} edge[(MAX_EDGE_NUM << 1) + 1];
int first[MAX_NODE_NUM + 1];
int depth[MAX_NODE_NUM + 1];
int now_edge[MAX_NODE_NUM + 1];
int start;
int end;
void addEdge(const int, const int, const int);
long long maxFlow(int);
int main() {
//init
memset(first, -1, sizeof(first));
int noden;
int edgen;
scanf("%d%d%d%d", &noden, &edgen, &start, &end);
while(edgen--) {
int from, to, flow;
scanf("%d%d%d", &from, &to, &flow);
addEdge(from, to, flow);
}
///init
//solve&print
printf("%lld\n", maxFlow(noden));
///solve&print
}
inline void addEdge(const int from, const int to, const int flow) {
static int cnt = -1;
edge[++cnt].to = to;
edge[cnt].flow = flow;
edge[cnt].next = first[from];
first[from] = cnt;
edge[++cnt].to = from;
edge[cnt].flow = 0;
edge[cnt].next = first[to];
first[to] = cnt;
return;
}
bool setDepth() {
std::queue<int> que;
while(!que.empty()) que.pop();
memset(depth, 0, sizeof(depth));
depth[start] = 1;
que.push(start);
while(!que.empty()) {
int now = que.front();
que.pop();
for(int edg = first[now]; edg != -1; edg = edge[edg].next) {
if(edge[edg].flow > 0 && depth[edge[edg].to] == 0) {
depth[edge[edg].to] = depth[now] + 1;
que.push(edge[edg].to);
}
}
}
return depth[end] != 0;
}
long long dfs(int now, long long flow) {
if(now == end) {
return flow;
}
long long res = 0;
for(int edg = now_edge[now]; edg != -1; edg = edge[edg].next) {
now_edge[now] = edg;
if(depth[edge[edg].to] != depth[now] + 1) continue;
if(edge[edg].flow <= 0) continue;
long long add = dfs(edge[edg].to, std::min(flow, (long long)edge[edg].flow));
edge[edg].flow -= add;
edge[edg ^ 1].flow += add;
flow -= add;
res += add;
if(flow == 0) break;
}
if(res == 0) {
depth[now] = 0;
}
return res;
}
long long maxFlow(int noden) {
long long res = 0;
while(setDepth()) {
for(int i = 1; i <= noden; ++i) {
now_edge[i] = first[i];
}
res += dfs(start, 0x7fffffffffffffffll);
}
return res;
}
后来写的好看点的:
class Dinic {
private:
struct Node {
Node() : first(-1) {}
int first;
int nowEdge;
int depth;
};
struct Edge {
Edge(int to, long long flow, int next) : to(to), flow(flow), next(next) {}
int to;
long long flow;
int next;
};
bool makeDepth(int start, int end) {
for(int i = 0; i < node.size(); ++i) {
node[i].depth = 0x7fffffff;
}
node[start].depth = 0;
std::queue<int> que;
que.push(start);
while(!que.empty()) {
int now = que.front();
que.pop();
for(int i = node[now].first; ~i; i = edge[i].next) {
if(edge[i].flow <= 0) continue;
if(node[edge[i].to].depth != 0x7fffffff) continue;
node[edge[i].to].depth = node[now].depth + 1;
que.push(edge[i].to);
}
}
return node[end].depth != 0x7fffffff;
}
long long dfs(int now, long long flow, int end) {
if(now == end) return flow;
long long res = 0;
for(int &i = node[now].nowEdge; ~i; i = edge[i].next) {
if(node[edge[i].to].depth != node[now].depth + 1) continue;
if(edge[i].flow == 0) continue;
long long delta = dfs(edge[i].to, std::min(flow, edge[i].flow), end);
edge[i].flow -= delta;
edge[i ^ 1].flow += delta;
flow -= delta;
res += delta;
}
if(res == 0) {
node[now].depth = 0;
}
return res;
}
std::vector<Node> node;
std::vector<Edge> edge;
public:
int newNode() {
Node temp;
node.push_back(temp);
return node.size() - 1;
}
void addEdge(int from, int to, long long flow) {
edge.push_back(Edge(to, flow, node[from].first));
node[from].first = edge.size() - 1;
edge.push_back(Edge(from, 0, node[to].first));
node[to].first = edge.size() - 1;
}
long long maxFlow(int start, int end) {
long long ret = 0;
while(makeDepth(start, end)) {
for(int i = 0; i < node.size(); ++i) {
node[i].nowEdge = node[i].first;
}
ret += dfs(start, 0x7fffffffffffffffll, end);
}
return ret;
}
};