Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <string>
- #include <vector>
- #include <set>
- #include <map>
- #include <algorithm>
- #include <ctime>
- #include <cmath>
- #include <functional>
- #include <cassert>
- #include <complex>
- #include <valarray>
- using namespace std;
- typedef pair<int, int> pii;
- #define mp make_pair
- #define X first
- #define Y second
- const int INF = (int)1e9 + 100;
- const int N = 555;
- const int M = 10100;
- int n, m;
- int cost[M];
- int ed[M][2];
- vector<pii> G[N];
- vector<int> g[N], rg[N];
- int ord[N];
- int ordSz;
- int col[N];
- int C;
- int minEdge[N];
- bool used[N];
- bool goodEdge[M];
- void read()
- {
- scanf("%d%d", &n, &m);
- for (int i = 0; i < m; i++)
- {
- int v, u, w;
- scanf("%d%d%d", &v, &u, &w);
- v--;u--;
- cost[i] = w;
- ed[i][0] = v;
- ed[i][1] = u;
- G[v].push_back(mp(u, i));
- }
- return;
- }
- void dfsOrd(int v)
- {
- used[v] = 1;
- for (int u : g[v])
- if (!used[u])
- dfsOrd(u);
- ord[ordSz++] = v;
- return;
- }
- void dfsColor(int v)
- {
- col[v] = C;
- for (int u : rg[v])
- if (col[u] == -1)
- dfsColor(u);
- return;
- }
- void dfsCheck(int v)
- {
- used[v] = 1;
- for (pii e : G[v])
- {
- if (cost[e.second] != 0) continue;
- int u = e.first;
- if (!used[u])
- {
- goodEdge[e.second] = true;
- dfsCheck(u);
- }
- }
- return;
- }
- bool check(int sz, int V)
- {
- for (int i = 0; i < sz; i++)
- used[i] = false;
- dfsCheck(V);
- for (int i = 0; i < sz; i++)
- if (!used[i])
- {
- for (int e = 0; e < m; e++)
- goodEdge[e] = false;
- return false;
- }
- return true;
- }
- void dfsAns(int v)
- {
- used[v] = true;
- for (pii e : G[v])
- {
- if (cost[e.second] != 0) continue;
- int u = e.first;
- if (used[u] || col[v] != col[u]) continue;
- goodEdge[e.second] = true;
- dfsAns(u);
- }
- return;
- }
- void solve(int sz, int V)
- {
- if (sz == 1) throw;
- for (int i = 0; i < sz; i++)
- minEdge[i] = INF;
- for (int v = 0; v < sz; v++)
- for (pii e : G[v])
- minEdge[e.first] = min(minEdge[e.first], cost[e.second]);
- for (int v = 0; v < sz; v++)
- for (pii e : G[v])
- if (e.first != V)
- cost[e.second] -= minEdge[e.first];
- if (check(sz, V))
- return;
- for (int v = 0; v < sz; v++)
- {
- g[v].clear();
- rg[v].clear();
- }
- for (int v = 0; v < sz; v++)
- for (pii e : G[v])
- if (e.first != V && cost[e.second] == 0)
- {
- g[v].push_back(e.first);
- rg[e.first].push_back(v);
- }
- ordSz = 0;
- for (int i = 0; i < sz; i++)
- used[i] = false;
- for (int v = 0; v < sz; v++)
- if (!used[v])
- dfsOrd(v);
- if (ordSz != sz) throw;
- reverse(ord, ord + sz);
- for (int v = 0; v < sz; v++)
- col[v] = -1;
- C = 0;
- for (int i = 0; i < sz; i++)
- {
- int v = ord[i];
- if (col[v] != -1) continue;
- dfsColor(v);
- C++;
- }
- if (C == sz) throw;
- vector<pii> NG[N];
- for (int i = 0; i < sz; i++)
- NG[i].clear();
- for (int v = 0; v < sz; v++)
- for (pii e : G[v])
- {
- int nv = col[v], nu = col[e.first];
- if (nv == nu) continue;
- NG[nv].push_back(mp(nu, e.second));
- }
- for (int v = 0; v < sz; v++)
- swap(G[v], NG[v]);
- int ncol[N];
- for (int v = 0; v < sz; v++)
- ncol[v] = col[v];
- solve(C, col[V]);
- for (int v = 0; v < sz; v++)
- col[v] = ncol[v];
- for (int v = 0; v < sz; v++)
- swap(G[v], NG[v]);
- for (int v = 0; v < sz; v++)
- used[v] = false;
- for (int v = 0; v < sz; v++)
- for (pii e : G[v])
- {
- int u = e.first;
- if (!used[u] && goodEdge[e.second])
- dfsAns(u);
- }
- return;
- }
- int main()
- {
- #ifdef LOCAL
- freopen ("input.txt", "r", stdin);
- freopen ("output.txt", "w", stdout);
- freopen ("err.txt", "w", stderr);
- #endif
- read();
- solve(n, 0);
- printf("%d\n", n - 1);
- for (int i = 0; i < m; i++)
- if (goodEdge[i])
- printf("%d ", i + 1);
- printf("\n");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement