Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <queue>
- #include <algorithm>
- #include <climits>
- #include <fstream>
- using namespace std;
- struct FlowEdge
- {
- int v, u;
- long long cap, flow;
- FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap), flow(0) {}
- };
- struct Dinic
- {
- const long long flow_inf = LLONG_MAX;
- vector<FlowEdge> edges;
- vector<vector<int>> adj;
- int n, m = 0;
- int s, t;
- vector<int> level, ptr;
- queue<int> q;
- Dinic(int n, int s, int t) : n(n), s(s), t(t)
- {
- adj.resize(n);
- level.resize(n);
- ptr.resize(n);
- }
- void add_edge(int v, int u, long long cap)
- {
- edges.emplace_back(v, u, cap);
- edges.emplace_back(u, v, 0);
- adj[v].push_back(m);
- adj[u].push_back(m + 1);
- m += 2;
- }
- bool bfs()
- {
- while (!q.empty())
- {
- int v = q.front();
- q.pop();
- for (int id : adj[v])
- {
- int u = edges[id].u;
- if (edges[id].cap - edges[id].flow < 1 || level[u] != -1)
- continue;
- level[u] = level[v] + 1;
- q.push(u);
- }
- }
- return level[t] != -1;
- }
- long long dfs(int v, long long pushed)
- {
- if (pushed == 0)
- return 0;
- if (v == t)
- return pushed;
- for (int &cid = ptr[v]; cid < (int)adj[v].size(); cid++)
- {
- int id = adj[v][cid];
- int u = edges[id].u;
- long long diff_cap_flow = edges[id].cap - edges[id].flow;
- if (level[v] + 1 != level[u] || diff_cap_flow < 1)
- continue;
- long long tr = dfs(u, min(pushed, diff_cap_flow));
- if (tr == 0)
- continue;
- edges[id].flow += tr;
- edges[id ^ 1].flow -= tr;
- // x ^ 1 == x - 1 if x % 2 else x + 1
- // edges[id ^ 1] is inverse edge: (u, v) -- (v, u)
- return tr;
- }
- return 0;
- }
- long long flow()
- {
- long long f = 0;
- while (true)
- {
- fill(level.begin(), level.end(), -1);
- level[s] = 0;
- q.push(s);
- if (!bfs())
- break;
- fill(ptr.begin(), ptr.end(), 0);
- while (long long pushed = dfs(s, flow_inf))
- {
- f += pushed;
- }
- }
- return f;
- }
- };
- long long build_network_and_find_max_flow(int n, int m, const vector<pair<int, int>> &edges, int x, int y)
- {
- int new_n = 2 * (n - 2) + 2; // (v^(0) and v^(1) for each v != x, y) + (x, y)
- vector<int> v0(n, -1), v1(n, -1);
- int idx = 0;
- for (int i = 0; i < n; i++)
- {
- if (i != x && i != y)
- {
- v0[i] = idx++;
- v1[i] = idx++;
- }
- }
- int source = idx++;
- int sink = idx++;
- Dinic dinic(new_n, source, sink);
- for (const auto &e : edges)
- {
- int u = e.first;
- int v = e.second;
- if (u == x || u == y || v == x || v == y)
- {
- if (u == x)
- {
- dinic.add_edge(source, v0[v], dinic.flow_inf);
- }
- else if (u == y)
- {
- dinic.add_edge(v1[v], sink, dinic.flow_inf);
- }
- else if (v == x)
- {
- dinic.add_edge(source, v0[u], dinic.flow_inf);
- }
- else if (v == y)
- {
- dinic.add_edge(v1[u], sink, dinic.flow_inf);
- }
- }
- else
- {
- dinic.add_edge(v1[u], v0[v], dinic.flow_inf);
- dinic.add_edge(v1[v], v0[u], dinic.flow_inf);
- }
- }
- for (int i = 0; i < n; i++)
- {
- if (i != x && i != y)
- {
- dinic.add_edge(v0[i], v1[i], 1);
- }
- }
- return dinic.flow();
- }
- int main()
- {
- ifstream infile("input.txt");
- if (!infile)
- {
- cerr << "Unable to open file input.txt";
- return 1;
- }
- int n, m;
- // cin >> n >> m;
- infile >> n >> m;
- vector<pair<int, int>> edges(m);
- for (int i = 0; i < m; i++)
- {
- int u, v;
- // cin >> u >> v;
- infile >> u >> v;
- edges[i] = {u - 1, v - 1}; // Convert to 0-based index
- }
- int x, y;
- // cin >> x >> y;
- infile >> x >> y;
- infile.close();
- // Convert to 0-based index
- x--;
- y--;
- long long maxflow = build_network_and_find_max_flow(n, m, edges, x, y);
- cout << maxflow << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement