Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <queue>
- #include <set>
- using namespace std;
- struct Edge {
- int from, to;
- long long cap, flow;
- Edge() = default;
- Edge(int a, int b, long long c, long long d) {
- from = a;
- to = b;
- cap = c;
- flow = d;
- }
- };
- long long INF = 1000000000;
- int m, n, k, l;
- vector<Edge> edges;
- vector<vector<int>> ind;
- vector<int> mount, pos;
- int A, B;
- vector<int> p, d;
- bool bfs(long long k_) {
- fill(d.begin(), d.end(), -1);
- queue<int> q;
- d[A] = 0;
- q.push(A);
- while(!q.empty()) {
- int v = q.front();
- q.pop();
- for (int i : ind[v]) {
- int to = edges[i].to;
- if (edges[i].cap - edges[i].flow < k_) {
- continue;
- }
- if (d[to] == -1) {
- d[to] = d[v] + 1;
- q.push(to);
- }
- }
- }
- return d[B] != -1;
- }
- long long dfs(int i, long long flow, long long k_){
- if(i == B){
- return flow;
- }
- for( ; p[i] < ind[i].size(); ++p[i]){
- int id = ind[i][p[i]];
- int to = edges[id].to;
- if (edges[id].cap - edges[id].flow < k_) {
- continue;
- }
- if(d[to] == d[i] + 1) {
- long long delta = dfs(to, min(flow, edges[id].cap - edges[id].flow), k_);
- if(delta > 0){
- edges[id].flow += delta;
- edges[id ^ 1].flow -= delta;
- return delta;
- }
- }
- }
- return 0;
- }
- void dfs2(int i, vector<int>& used) {
- used[i] = 1;
- for (int j : ind[i]) {
- if (edges[j].cap - edges[j].flow > 0 && !used[edges[j].to]) {
- dfs2(edges[j].to, used);
- }
- }
- }
- int main() {
- cin >> m >> n >> k >> l;
- ind.resize(m * n * 2);
- p.resize(m * n * 2);
- d.resize(m * n * 2);
- for (int i = 0; i < k; ++i) {
- int x, y;
- cin >> x >> y;
- --x; --y;
- mount.push_back(x * n + y);
- }
- for (int i = 0; i < l; ++i) {
- int x, y;
- cin >> x >> y;
- --x; --y;
- pos.push_back(x * n + y);
- }
- {
- int x, y;
- cin >> x >> y;
- --x; --y;
- A = x * n + y;
- cin >> x >> y;
- --x; --y;
- B = x * n + y;
- }
- for (int i = 0; i < m; ++i) {
- for (int j = 0; j < n; ++j) {
- int num = i * n + j;
- if (find(mount.begin(), mount.end(), num) != mount.end()) {
- edges.emplace_back(num, num + n * m, 0, 0);
- ind[num].push_back(edges.size() - 1);
- edges.emplace_back(num + n * m, num, 0, 0);
- ind[num + n * m].push_back(edges.size() - 1);
- } else if (find(pos.begin(), pos.end(), num) != pos.end()) {
- edges.emplace_back(num, num + n * m, 1, 0);
- ind[num].push_back(edges.size() - 1);
- edges.emplace_back(num + n * m, num, 0, 0);
- ind[num + n * m].push_back(edges.size() - 1);
- } else {
- edges.emplace_back(num, num + n * m, INF, 0);
- ind[num].push_back(edges.size() - 1);
- edges.emplace_back(num + n * m, num, 0, 0);
- ind[num + n * m].push_back(edges.size() - 1);
- }
- if (i > 0) {
- int num_to = (i - 1) * n + j;
- edges.emplace_back(num + n * m, num_to, INF, 0);
- ind[num + n * m].push_back(edges.size() - 1);
- edges.emplace_back(num_to, num + n * m, 0, 0);
- ind[num_to].push_back(edges.size() - 1);
- }
- if (j > 0) {
- int num_to = i * n + (j - 1);
- edges.emplace_back(num + n * m, num_to, INF, 0);
- ind[num + n * m].push_back(edges.size() - 1);
- edges.emplace_back(num_to, num + n * m, 0, 0);
- ind[num_to].push_back(edges.size() - 1);
- }
- if (i < m - 1) {
- int num_to = (i + 1) * n + j;
- edges.emplace_back(num + n * m, num_to, INF, 0);
- ind[num + n * m].push_back(edges.size() - 1);
- edges.emplace_back(num_to, num + n * m, 0, 0);
- ind[num_to].push_back(edges.size() - 1);
- }
- if (j < n - 1) {
- int num_to = i * n + (j + 1);
- edges.emplace_back(num + n * m, num_to, INF, 0);
- ind[num + n * m].push_back(edges.size() - 1);
- edges.emplace_back(num_to, num + n * m, 0, 0);
- ind[num_to].push_back(edges.size() - 1);
- }
- }
- }
- long long ans = 0;
- for (int k_ = 30; k_ >= 0; --k_) {
- while (bfs(1LL << k_)) {
- fill(p.begin(), p.end(), 0);
- long long flow = dfs(A, INF, 1LL << k_);
- while (flow != 0) {
- ans += flow;
- flow = dfs(A, INF, 1LL << k_);
- }
- }
- }
- if (ans >= INF) {
- cout << -1;
- return 0;
- }
- cout << ans << "\n";
- set<pair<int, int>> res;
- vector<int> used(m * n * 2, 0);
- dfs2(A, used);
- for (auto e : edges) {
- if (used[e.from] != used[e.to] && find(pos.begin(), pos.end(), min(e.from, e.to)) != pos.end()) {
- res.insert({min(e.from, e.to) / n + 1, min(e.from, e.to) % n + 1});
- }
- }
- for (auto p_ : res) {
- cout << p_.first << " " << p_.second << "\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement