POJ 3469 最小割

来源:互联网 发布:js window.onload方法 编辑:程序博客网 时间:2024/05/18 00:30
#include <cstdio>#include <algorithm>#include <vector>#include <iostream>#include <queue>#include <cstring>using namespace std;const int INF = 0x3f3f3f3f;const int MAX_N = 2E4 + 10;const int MAX_M = 2E5 + 10;int N, M, A[MAX_N], B[MAX_N], b[MAX_M], a[MAX_M], w[MAX_M];struct Edge{int from, to, cap, flow;Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {}};struct Dinic{int n, m, s, t;vector<Edge>edges;vector<int>G[MAX_N];bool vis[MAX_N];int d[MAX_N], cur[MAX_N];void add_edge(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 < 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 < 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 max_flow(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;}};Dinic D;void solve(){int s = N, t = s + 1;for (int i = 0; i < N; i++)D.add_edge(i, t, A[i]), D.add_edge(s, i, B[i]);for (int i = 0; i < M; i++)D.add_edge(a[i] - 1, b[i] - 1, w[i]), D.add_edge(b[i] - 1, a[i] - 1, w[i]);printf("%d\n", D.max_flow(s, t));}int main(int argc, char const *argv[]){while (~scanf("%d%d", &N, &M) && N + M){for (int i = 0; i < N; i++)scanf("%d%d", &A[i], &B[i]);for (int i = 0; i < M; i++)scanf("%d%d%d", &a[i], &b[i], &w[i]);solve();}return 0;}


这道题目白书上有题解,可惜他的算法过不了时限。。。。。

需要用刘汝佳的算法,Dinic和ISAP都可以。

0 0
原创粉丝点击