1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| #include <bits/stdc++.h>
#define N 100010 #define M 300010 using namespace std;
typedef long long ll;
struct Edge { int to, ne, w; } edges[M << 1]; int h[N], hs[N], idx = 0; int scc_cnt = 0, dfs_cnt = 0; int scc_id[N], scc_size[N]; int dfn[N], low[N]; int dist[N]; stack<int> stk; bool in_stk[N];
void add(int head[], int a, int b, int w) { idx++; edges[idx].to = b; edges[idx].ne = head[a]; edges[idx].w = w; head[a] = idx; }
void tarjan(int u) { dfn[u] = low[u] = ++dfs_cnt; stk.push(u); in_stk[u] = true; for (int i = h[u]; ~i; i = edges[i].ne) { int j = edges[i].to; if (!dfn[j]) { tarjan(j); low[u] = min(low[u], low[j]); } else if (in_stk[j]) { low[u] = min(low[u], dfn[j]); } } if (dfn[u] == low[u]) { scc_cnt++; int t; do { t = stk.top(); stk.pop(); in_stk[t] = false; scc_id[t] = scc_cnt; scc_size[scc_cnt]++; } while (t != u); } }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
memset(h, -1, sizeof h); memset(hs, -1, sizeof hs);
int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) add(h, 0, i, 1); while (m--) { int t, a, b; cin >> t >> a >> b; if (t == 1) { add(h, a, b, 0); add(h, b, a, 0); } else if (t == 2) add(h, a, b, 1); else if (t == 3) add(h, b, a, 0); else if (t == 4) add(h, b, a, 1); else add(h, a, b, 0); } tarjan(0); for (int i = 0; i <= n; i++) { for (int j = h[i]; ~j; j = edges[j].ne) { int k = edges[j].to; int a = scc_id[i], b = scc_id[k]; if (a == b) { if (edges[j].w > 0) { cout << -1 << endl; return 0; } } else add(hs, a, b, edges[j].w); } } for (int i = scc_cnt; i >= 1; i--) { for (int j = hs[i]; ~j; j = edges[j].ne) { int k = edges[j].to; dist[k] = max(dist[k], dist[i] + edges[j].w); } } ll res = 0; for (int i = 1; i <= scc_cnt; i++) res += dist[i] * scc_size[i]; cout << res << endl; return 0; }
|