Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <fstream>
- #include <vector>
- #include <numeric>
- #include <algorithm>
- #include <set>
- #include <map>
- #include <cmath>
- #include <stack>
- #include <deque>
- #include <string>
- #include <ctime>
- #include <bitset>
- #include <queue>
- #include <cassert>
- #include<unordered_set>
- #include<unordered_map>
- #include<string.h>
- #include <random>
- #include <chrono>
- #include <math.h>
- using namespace std;
- #define ll long long
- #define ld long double
- #define pi pair<int, int>
- #define pll pair<ll, ll>
- #define mint map<int, int>*;
- #define vi vector<int>
- #define int long long
- #pragma GCC optimize("O3,unroll-loops")
- #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
- template<typename T>
- istream& operator>>(istream& is, vector<T>& v) {
- for (T& o : v) {
- is >> o;
- }
- return is;
- }
- class Query {
- public:
- int l = 0;
- int r = 0;
- int idx = 0;
- Query(int L, int R, int Num) {
- l = L;
- r = R;
- idx = Num;
- }
- };
- int NOD(int a, int b) {
- if (a < 0 || b < 0) return NOD(abs(a), abs(b));
- return b ? NOD(b, a % b) : a;
- }
- const ld EPS = 1e-6;
- const ll INF = 1e16 + 3;
- const ll MOD1 = 1e9 + 7;
- const ll POWER = 5;
- const ll HASHMOD1 = 939999971;
- const ll HASHMOD2 = 23;
- const ll MOD2 = 1e9 + 7;
- const ld PHI = atan(1) * 4;
- const ll MOD3 = 998244353;
- const int root = 31;
- const int root_1 = 128805723;
- const int root_pw = 1 << 23;
- vector<int> dX = { 1, 0, -1, 0, };
- vector<int> dY = { 0, 1, 0, -1 };
- mt19937 MT(chrono::steady_clock::now().time_since_epoch().count());
- const int block_size = 500;
- const int maxN = 1e6 + 5;
- vector<vector<int>> g;
- vector<int> d;
- vector<int> ptr;
- struct Edge {
- public:
- int u = 0; int v = 0;
- int cap = 0; int flow = 0;
- Edge(int v1, int v2, int capacity, int Flow) {
- flow = Flow; u = v1; v = v2; cap = capacity;
- }
- };
- vector<Edge> allEdges;
- void addNewEdge(int v1, int v2, int capacity) {
- Edge eTo = Edge(v1, v2, capacity, 0);
- Edge eBack = Edge(v2, v1, 0, 0);
- g[v1].push_back(allEdges.size());
- allEdges.push_back(eTo);
- g[v2].push_back(allEdges.size());
- allEdges.push_back(eBack);
- }
- bool BFSFLOW(int s, int t, int limit, int N) {
- d.assign(N + 1, INF);
- queue<int> q;
- q.push(s); d[s] = 0;
- while (!q.empty() && d[t] == INF) {
- int v = q.front(); q.pop();
- for (int j = 0; j < g[v].size(); ++j) {
- int id = g[v][j];
- int goingTo = allEdges[id].v;
- if (d[goingTo] == INF && allEdges[id].flow < allEdges[id].cap && allEdges[id].cap - allEdges[id].flow >= limit) {
- q.push(goingTo);
- d[goingTo] = d[v] + 1;
- }
- }
- }
- return d[t] != INF;
- }
- vector<int> ans;
- vector<vector<int>> dek;
- int DFSFLOW(int v, int flow, int t) {
- if (!flow) return 0;
- if (v == t) return flow;
- for (; ptr[v] < g[v].size(); ptr[v]++) {
- int newId = g[v][ptr[v]]; int TO = allEdges[newId].v;
- if (d[TO] != d[v] + 1) continue;
- int tmp = allEdges[newId].cap - allEdges[newId].flow;
- int pushed = DFSFLOW(TO, min(flow, tmp), t);
- if (pushed) {
- allEdges[newId].flow += pushed;
- allEdges[newId ^ 1].flow -= pushed;
- return pushed;
- }
- }
- return 0;
- }
- int dinic(int s, int t, int N) {
- int flow = 0;
- int k = (1 << 30);
- while (k > 0) {
- while (BFSFLOW(s, t, k, N)) {
- ptr.assign(N + 1, 0);
- while (int pushed = DFSFLOW(s, INF, t)) {
- flow += pushed;
- }
- }
- k /= 2;
- }
- return flow;
- }
- int dfs(int v, int flow, int t) {
- if (!flow) return 0;
- if (v == t) return flow;
- for (int u = 0; u < g[v].size(); u++) {
- int newId = g[v][u]; int TO = allEdges[newId].v;
- int tmp = allEdges[newId].flow;
- if (tmp <= 0) {
- continue;
- }
- int pushed = dfs(TO, min(flow, tmp), t);
- if (pushed) {
- dek[ans.size()].push_back((newId / 2) + 1);
- allEdges[newId].flow -= pushed;
- allEdges[newId ^ 1].flow += pushed;
- return pushed;
- }
- }
- return 0;
- }
- void dekomposition(int n) {
- int fl = dfs(1, INF, n);
- while (fl != 0) {
- ans.push_back(fl);
- dek.emplace_back();
- fl = dfs(1, INF, n);
- }
- }
- void solve() {
- int N = 0, M = 0; cin >> N >> M;
- dek.emplace_back();
- g.assign(N + 1, vector<int>());
- for (int j = 0; j < M; ++j) {
- int a = 0, b = 0, cap = 0; cin >> a >> b >> cap;
- addNewEdge(a, b, cap);
- }
- dinic(1, N, N);
- dekomposition(N);
- cout << ans.size() << endl;
- for (int i = 0; i < ans.size(); ++i) {
- cout << ans[i] << " " << dek[i].size() << " ";
- reverse(dek[i].begin(), dek[i].end());
- for (auto j : dek[i]) {
- cout << j << " ";
- }
- cout << endl;
- }
- }
- signed main() {
- ios_base::sync_with_stdio(false);
- cin.tie(0);
- cout.tie(0);
- cout << setprecision(12);
- int T = 1;
- while (T--) {
- solve();
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment