Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <queue>
- #include <utility>
- #include <tuple>
- #include <algorithm>
- #define endl '\n'
- using namespace std;
- const int MAXN = 500005;
- const int INF = 1 << 30;
- int n, m, w, h;
- int lev[MAXN], idx[MAXN], vis[MAXN], rem[MAXN];
- vector<int> g[MAXN][2];
- vector<vector<int>> order;
- tuple<int, int, int> pos[MAXN];
- pair<int, int> range[MAXN];
- vector<int> active, nxt[MAXN];
- bool comp(int x, int y)
- {
- return pos[x] < pos[y];
- }
- void Init()
- {
- ios :: sync_with_stdio(false);
- cin.tie(NULL); cout.tie(NULL);
- cin >> n >> m;
- for (int i = 1; i <= m; ++ i)
- {
- int u, d;
- cin >> u >> d;
- g[u][0].push_back(d);
- g[d][1].push_back(u);
- }
- int b;
- cin >> b;
- }
- void CalcLevels(int u, int l)
- {
- lev[u] = l;
- h = max(h, lev[u]);
- for (int v : g[u][0])
- {
- if (lev[v] == 0) CalcLevels(v, l + 1);
- }
- }
- int level, minv, maxv;
- void Enumerate(int u, int d)
- {
- vis[u] = 1;
- int dir = (lev[u] == level) ? 0 : 1;
- for (int v : g[u][dir])
- {
- if (vis[v] != 0 or g[v][dir ^ 1].size() == 1) continue;
- get<2>(pos[v]) = get<2>(pos[u]) + d;
- Enumerate(v, d);
- d += 2;
- }
- }
- void SortLevel(int l)
- {
- for (int i = l; i <= l + 1; ++ i)
- {
- if (i > h) break;
- for (int j : order[l])
- {
- vis[j] = 0;
- }
- }
- if (l == 1)
- {
- for (int u : order[1])
- {
- get<0>(pos[u]) = 0;
- get<1>(pos[u]) = 0;
- }
- }
- else
- {
- for (int u : order[l])
- {
- int mini = +INF, maxi = -INF;
- for (int v : g[u][1])
- {
- mini = min(mini, idx[v]);
- maxi = max(maxi, idx[v]);
- }
- get<0>(pos[u]) = mini;
- get<1>(pos[u]) = maxi;
- }
- }
- vector<int> equ;
- int start = 0;
- for (int i = 0; i < order[l].size(); ++ i)
- {
- int u = order[l][i];
- if (g[u][0].size() == 1)
- {
- int v = g[u][0][0];
- if (vis[v] != -1) equ.push_back(v);
- else vis[v] = -1;
- }
- else start = u;
- }
- for (int v : equ) vis[v] = 0;
- level = l;
- minv = maxv = 0;
- get<2>(pos[start]) = 0;
- if (start != 0) Enumerate(start, -1);
- for (int v : equ)
- {
- for (int u : g[v][1])
- {
- if (g[u][0].size() == 1)
- {
- get<2>(pos[u]) = get<2>(pos[v]);
- }
- }
- }
- for (int u : order[l])
- {
- if (minv == 0 or get<2>(pos[u]) < get<2>(pos[minv])) minv = u;
- else if (get<2>(pos[u]) == get<2>(pos[minv]) and pos[u] > pos[minv]) minv = u;
- if (maxv == 0 or get<2>(pos[u]) > get<2>(pos[maxv])) maxv = u;
- else if (get<2>(pos[u]) == get<2>(pos[maxv]) and pos[u] < pos[maxv]) maxv = u;
- }
- if (pos[minv] > pos[maxv])
- {
- for (int u : order[l])
- {
- get<2>(pos[u]) *= -1;
- }
- }
- sort(order[l].begin(), order[l].end(), comp);
- for (int i = 0; i < order[l].size(); ++ i)
- {
- idx[order[l][i]] = i;
- }
- }
- void Solve()
- {
- for (int i = 1; i <= n; ++ i)
- {
- int above = 0, below = 0;
- for (int j : g[i][0])
- {
- if (below == 0 or idx[below] < idx[j]) below = j;
- }
- for (int j : g[i][1])
- {
- if (above == 0 or idx[above] < idx[j]) above = j;
- }
- if (above != 0 and idx[above] != 0)
- {
- nxt[above].push_back(i);
- rem[i]++;
- }
- if (below != 0 and idx[below] != 0)
- {
- nxt[below].push_back(i);
- rem[i]++;
- }
- if (idx[i] != 0) rem[i]++;
- }
- queue<int> q;
- active.resize(h + 1);
- for (int i = 1; i <= h; ++ i)
- {
- active[i] = 0;
- range[order[i].front()].first = 0;
- if (rem[order[i][0]] == 0) q.push(order[i][0]);
- }
- while (!q.empty())
- {
- w++;
- queue<int> qnew;
- while (!q.empty())
- {
- int e = q.front();
- q.pop();
- int l = lev[e];
- if (active[l] + 1 != order[l].size())
- {
- int enew = order[l][++active[l]];
- range[e].second = w;
- range[enew].first = w;
- if (--rem[enew] == 0) qnew.push(enew);
- for (int f : nxt[enew])
- {
- rem[f]--;
- if (rem[f] == 0) qnew.push(f);
- }
- }
- }
- swap(q, qnew);
- }
- for (int i = 1; i <= h; ++ i)
- {
- range[order[i].back()].second = w;
- }
- }
- int main()
- {
- Init();
- for (int i = 1; i <= n; ++ i)
- {
- if (g[i][1].size() == 0) CalcLevels(i, 1);
- }
- order.resize(h + 1);
- for (int i = 1; i <= n; ++ i)
- {
- order[lev[i]].push_back(i);
- }
- for (int i = 1; i <= h; ++ i)
- {
- SortLevel(i);
- }
- Solve();
- cout << h << ' ' << w << endl;
- for (int i = 1; i <= h; ++ i)
- {
- cout << order[i].size();
- for (int s : order[i])
- {
- cout << ' ' << s << ' ' << range[s].second - range[s].first;
- }
- cout << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement