Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <vector>
- #include <string>
- #include <iostream>
- #include <map>
- #include <set>
- #include <bit>
- #include <algorithm>
- #include <queue>
- #include <exception>
- using namespace std;
- struct Edge {
- int a;
- int b;
- int capacity;
- int flow = 0;
- int other(int v) const {
- if (v == a) {
- return b;
- }
- return a;
- }
- int capacityTo(int v) const {
- if (v == a) {
- return flow;
- }
- return capacity - flow;
- }
- void addFlowTo(int v, int delta) {
- if (v == a) {
- flow -= delta;
- } else {
- flow += delta;
- }
- }
- int checkFLow(int v){
- return v == a ? 0 : flow;
- }
- };
- class Graph {
- vector<Edge> edges;
- vector<vector<int>> graph;
- vector<int> parents;
- void bfs(int start, int finish) {
- queue<int> q;
- q.push(start);
- while (!q.empty() && parents[finish] == -1) {
- const auto vertex = q.front();
- q.pop();
- for (const auto e: graph[vertex]) {
- // 1e9 means unreached
- int to = edges[e].other(vertex);
- if (parents[to] == -1 && edges[e].capacityTo(to)) {
- parents[to] = e;
- q.push(to);
- }
- }
- }
- }
- int hasPath(int start, int finish) {
- parents.assign(graph.size(), -1);
- bfs(start, finish);
- if (parents[finish] != -1) {
- int min_capacity = edges[parents[finish]].capacityTo(finish);
- for (int v = finish; v != start; v = edges[parents[v]].other(v)) {
- auto cur_capacity = edges[parents[v]].capacityTo(v);
- if (min_capacity > cur_capacity) {
- min_capacity = cur_capacity;
- }
- }
- return min_capacity;
- } else {
- return -1;
- }
- }
- void addFlow(int start, int finish, int deltaFlow) {
- for (int v = finish; v != start; v = edges[parents[v]].other(v))
- edges[parents[v]].addFlowTo(v, deltaFlow);
- }
- public:
- Graph( vector<Edge> edges, vector<vector<int>> graph) :
- edges(edges), graph(graph) {}
- long long maxFlow(int start, int finish) {
- long long flow = 0;
- int delta = hasPath(start, finish);
- while (delta != -1) {
- addFlow(start, finish, delta);
- flow += delta;
- delta = hasPath(start, finish);
- }
- return flow;
- }
- vector<int> bfs_ans(int start, int finish) {
- parents.assign(graph.size(), -1);
- queue<int> q;
- q.push(start);
- while (!q.empty() && parents[finish] == -1) {
- const auto vertex = q.front();
- q.pop();
- for (const auto e: graph[vertex]) {
- // 1e9 means unreached
- int to = edges[e].other(vertex);
- if (parents[to] == -1 && edges[e].checkFLow(to) > 0) {
- parents[to] = e;
- q.push(to);
- }
- }
- }
- vector<int> way;
- int cur = finish;
- way.push_back(finish);
- while (cur != start) {
- edges[parents[cur]].flow = 0;
- cur = edges[parents[cur]].other(cur);
- way.push_back(cur);
- }
- reverse(way.begin(), way.end());
- return way;
- }
- };
- int main() {
- int n_vertexes, n_edges;
- cin >> n_vertexes >> n_edges;
- int start, finish;
- cin >> start >> finish;
- --start;
- --finish;
- vector<Edge> edges;
- vector<vector<int>> graph(n_vertexes);
- for (size_t i = 0; i < n_edges; ++i) {
- int from, to;
- cin >> from >> to;
- --from;
- --to;
- edges.push_back({from, to, 1});
- graph[from].push_back(edges.size() - 1);
- graph[to].push_back(edges.size() - 1);
- }
- Graph g( edges, graph);
- auto f = g.maxFlow(start, finish);
- if (f < 2) {
- cout << f << " NO";
- } else {
- cout << "YES" << "\n";
- for (auto el: g.bfs_ans(start, finish)) {
- cout << el+1 << " ";
- }
- cout << "\n";
- for (auto el: g.bfs_ans(start, finish)) {
- cout << el+1 << " ";
- }
- cout << "\n";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement