Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <cmath>
- #include <ctime>
- #include <cassert>
- #include <cstdio>
- #include <queue>
- #include <set>
- #include <map>
- #include <fstream>
- #include <cstdlib>
- #include <string>
- #include <cstring>
- #include <algorithm>
- #include <numeric>
- #define mp make_pair
- #define mt make_tuple
- #define fi first
- #define se second
- #define pb push_back
- #define all(x) (x).begin(), (x).end()
- #define rall(x) (x).rbegin(), (x).rend()
- #define forn(i, n) for (int i = 0; i < (int)(n); ++i)
- #define for1(i, n) for (int i = 1; i <= (int)(n); ++i)
- #define ford(i, n) for (int i = (int)(n) - 1; i >= 0; --i)
- #define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)
- using namespace std;
- typedef pair<int, int> pii;
- typedef vector<int> vi;
- typedef vector<pii> vpi;
- typedef vector<vi> vvi;
- typedef long long i64;
- typedef vector<i64> vi64;
- typedef vector<vi64> vvi64;
- template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
- template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }
- struct TEdge {
- int to, w, id;
- TEdge(int to = 0, int w = 0, int id = 0)
- : to(to)
- , w(w)
- , id(id)
- {
- }
- };
- typedef vector< vector<TEdge> > TGraph;
- void dfs0(int v, TGraph &e, vi &vis, vi &tre) {
- vis[v] = 1;
- for (TEdge w: e[v]) {
- if (w.w || vis[w.to]) continue;
- tre.pb(w.id);
- dfs0(w.to, e, vis, tre);
- }
- }
- void dfs_ord(int v, TGraph &e, vi &vis, vi &ord) {
- if (vis[v]) return;
- vis[v] = 1;
- for (TEdge w: e[v]) dfs_ord(w.to, e, vis, ord);
- ord.pb(v);
- }
- void dfs_comp(int v, TGraph &e, vi &vis, vi &comp, int cc) {
- if (vis[v]) return;
- comp[v] = cc;
- vis[v] = 1;
- for (TEdge w: e[v]) dfs_comp(w.to, e, vis, comp, cc);
- }
- void dfs_cc0(int v, TGraph &e, vi &vis, vi &comp, vi &tre) {
- if (vis[v]) return;
- vis[v] = 1;
- for (TEdge w: e[v]) {
- if (vis[w.to] || comp[w.to] != comp[v]) continue;
- tre.pb(w.id);
- dfs_cc0(w.to, e, vis, comp, tre);
- }
- }
- TGraph rev(TGraph g) {
- int n = g.size();
- TGraph rg(n);
- forn(i, n) for (TEdge w: g[i]) rg[w.to].pb(TEdge(i, w.w, w.id));
- return rg;
- }
- vi condense(TGraph &e) {
- int n = e.size();
- vi vis(n), ord;
- forn(i, n) dfs_ord(i, e, vis, ord);
- reverse(all(ord));
- vis.assign(n, 0);
- TGraph re = rev(e);
- vi comp(n);
- int cc = 0;
- for (int v: ord) {
- if (vis[v]) continue;
- dfs_comp(v, re, vis, comp, cc++);
- }
- return comp;
- }
- vi mst(int v, TGraph e) {
- // cerr << e.size() << '\n';
- int n = e.size();
- vi pot(n, 1e9);
- forn(i, n) for (TEdge w: e[i]) uin(pot[w.to], w.w);
- TGraph e0(n);
- forn(i, n) for (TEdge &w: e[i]) {
- w.w -= pot[w.to];
- if (!w.w) e0[i].pb(w);
- }
- vi vis(n);
- vi tre;
- dfs0(v, e0, vis, tre);
- if (tre.size() == n - 1) return tre;
- vi comp = condense(e0);
- int cc = *max_element(all(comp)) + 1;
- TGraph ne(cc);
- forn(i, n) for (TEdge w: e[i]) {
- if (comp[i] != comp[w.to]) ne[comp[i]].pb(TEdge(comp[w.to], w.w, w.id));
- }
- vi cmst = mst(comp[v], ne);
- set<int> cid(all(cmst));
- vis.assign(n, 0);
- dfs_cc0(v, e0, vis, comp, cmst);
- forn(i, n) for (TEdge w: e[i]) {
- if (cid.count(w.id)) dfs_cc0(w.to, e0, vis, comp, cmst);
- }
- return cmst;
- }
- int main() {
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.precision(10);
- cout << fixed;
- #ifdef LOCAL_DEFINE
- freopen("input.txt", "rt", stdin);
- #endif
- int N, M;
- cin >> N >> M;
- TGraph e(N);
- forn(i, M) {
- int x, y, z;
- cin >> x >> y >> z;
- --x; --y;
- e[x].pb(TEdge(y, z, i + 1));
- }
- vi ans = mst(0, e);
- cout << ans.size() << '\n';
- for (int x: ans) cout << x << ' ';
- cout << '\n';
- #ifdef LOCAL_DEFINE
- cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment