Advertisement
kub3

xy_vss

May 20th, 2024
562
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.67 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <queue>
  4. #include <algorithm>
  5. #include <climits>
  6. #include <fstream>
  7.  
  8. using namespace std;
  9.  
  10. struct FlowEdge
  11. {
  12.     int v, u;
  13.     long long cap, flow;
  14.     FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap), flow(0) {}
  15. };
  16.  
  17. struct Dinic
  18. {
  19.     const long long flow_inf = LLONG_MAX;
  20.     vector<FlowEdge> edges;
  21.     vector<vector<int>> adj;
  22.     int n, m = 0;
  23.     int s, t;
  24.     vector<int> level, ptr;
  25.     queue<int> q;
  26.  
  27.     Dinic(int n, int s, int t) : n(n), s(s), t(t)
  28.     {
  29.         adj.resize(n);
  30.         level.resize(n);
  31.         ptr.resize(n);
  32.     }
  33.  
  34.     void add_edge(int v, int u, long long cap)
  35.     {
  36.         edges.emplace_back(v, u, cap);
  37.         edges.emplace_back(u, v, 0);
  38.         adj[v].push_back(m);
  39.         adj[u].push_back(m + 1);
  40.         m += 2;
  41.     }
  42.  
  43.     bool bfs()
  44.     {
  45.         while (!q.empty())
  46.         {
  47.             int v = q.front();
  48.             q.pop();
  49.             for (int id : adj[v])
  50.             {
  51.                 int u = edges[id].u;
  52.                 if (edges[id].cap - edges[id].flow < 1 || level[u] != -1)
  53.                     continue;
  54.                 level[u] = level[v] + 1;
  55.                 q.push(u);
  56.             }
  57.         }
  58.         return level[t] != -1;
  59.     }
  60.  
  61.     long long dfs(int v, long long pushed)
  62.     {
  63.         if (pushed == 0)
  64.             return 0;
  65.         if (v == t)
  66.             return pushed;
  67.         for (int &cid = ptr[v]; cid < (int)adj[v].size(); cid++)
  68.         {
  69.             int id = adj[v][cid];
  70.             int u = edges[id].u;
  71.             long long diff_cap_flow = edges[id].cap - edges[id].flow;
  72.             if (level[v] + 1 != level[u] || diff_cap_flow < 1)
  73.                 continue;
  74.             long long tr = dfs(u, min(pushed, diff_cap_flow));
  75.             if (tr == 0)
  76.                 continue;
  77.             edges[id].flow += tr;
  78.             edges[id ^ 1].flow -= tr;
  79.             // x ^ 1 == x - 1 if x % 2 else x + 1
  80.             // edges[id ^ 1] is inverse edge: (u, v) -- (v, u)
  81.             return tr;
  82.         }
  83.         return 0;
  84.     }
  85.  
  86.     long long flow()
  87.     {
  88.         long long f = 0;
  89.         while (true)
  90.         {
  91.             fill(level.begin(), level.end(), -1);
  92.             level[s] = 0;
  93.             q.push(s);
  94.             if (!bfs())
  95.                 break;
  96.  
  97.             fill(ptr.begin(), ptr.end(), 0);
  98.             while (long long pushed = dfs(s, flow_inf))
  99.             {
  100.                 f += pushed;
  101.             }
  102.         }
  103.         return f;
  104.     }
  105. };
  106.  
  107. long long build_network_and_find_max_flow(int n, int m, const vector<pair<int, int>> &edges, int x, int y)
  108. {
  109.     int new_n = 2 * (n - 2) + 2; // (v^(0) and v^(1) for each v != x, y) + (x, y)
  110.  
  111.     vector<int> v0(n, -1), v1(n, -1);
  112.     int idx = 0;
  113.     for (int i = 0; i < n; i++)
  114.     {
  115.         if (i != x && i != y)
  116.         {
  117.             v0[i] = idx++;
  118.             v1[i] = idx++;
  119.         }
  120.     }
  121.     int source = idx++;
  122.     int sink = idx++;
  123.  
  124.     Dinic dinic(new_n, source, sink);
  125.  
  126.     for (const auto &e : edges)
  127.     {
  128.         int u = e.first;
  129.         int v = e.second;
  130.         if (u == x || u == y || v == x || v == y)
  131.         {
  132.             if (u == x)
  133.             {
  134.                 dinic.add_edge(source, v0[v], dinic.flow_inf);
  135.             }
  136.             else if (u == y)
  137.             {
  138.                 dinic.add_edge(v1[v], sink, dinic.flow_inf);
  139.             }
  140.             else if (v == x)
  141.             {
  142.                 dinic.add_edge(source, v0[u], dinic.flow_inf);
  143.             }
  144.             else if (v == y)
  145.             {
  146.                 dinic.add_edge(v1[u], sink, dinic.flow_inf);
  147.             }
  148.         }
  149.         else
  150.         {
  151.             dinic.add_edge(v1[u], v0[v], dinic.flow_inf);
  152.             dinic.add_edge(v1[v], v0[u], dinic.flow_inf);
  153.         }
  154.     }
  155.  
  156.     for (int i = 0; i < n; i++)
  157.     {
  158.         if (i != x && i != y)
  159.         {
  160.             dinic.add_edge(v0[i], v1[i], 1);
  161.         }
  162.     }
  163.  
  164.     return dinic.flow();
  165. }
  166.  
  167. int main()
  168. {
  169.     ifstream infile("input.txt");
  170.     if (!infile)
  171.     {
  172.         cerr << "Unable to open file input.txt";
  173.         return 1;
  174.     }
  175.  
  176.     int n, m;
  177.     // cin >> n >> m;
  178.     infile >> n >> m;
  179.  
  180.     vector<pair<int, int>> edges(m);
  181.     for (int i = 0; i < m; i++)
  182.     {
  183.         int u, v;
  184.         // cin >> u >> v;
  185.         infile >> u >> v;
  186.         edges[i] = {u - 1, v - 1}; // Convert to 0-based index
  187.     }
  188.  
  189.     int x, y;
  190.     // cin >> x >> y;
  191.     infile >> x >> y;
  192.     infile.close();
  193.  
  194.     // Convert to 0-based index
  195.     x--;
  196.     y--;
  197.  
  198.     long long maxflow = build_network_and_find_max_flow(n, m, edges, x, y);
  199.  
  200.     cout << maxflow << endl;
  201.     return 0;
  202. }
  203.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement