typedeflonglong LL; constint N = 2000010, M = 4000010; int h[N], e[M], ne[M], w[M], idx; int fa[N], fe[N]; bool cir[N]; int dfn[N], low[N], timestamp; LL s[N], stot[N]; int n, square;
voidadd(int a, int b, int c){ e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; }
voidbuildcir(int x, int y, int edge){ LL sum = w[edge]; for (int k = y; k != x; k = fa[k]) s[k] = sum, sum += w[fe[k]], cir[fe[k]] = cir[fe[k]^1] = true; cir[edge] = cir[edge^1] = true; s[x] = stot[x] = sum; ++square; for (int k = y; k != x; k = fa[k]) stot[k] = sum, add(square, k, 0); add(square, x, 0); }
voidtarjan(int u, int from){ dfn[u] = low[u] = ++timestamp; for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (!dfn[j]) { fe[j] = i, fa[j] = u; tarjan(j, i); low[u] = min(low[u], low[j]); } elseif (i != (from ^ 1)) low[u] = min(low[u], dfn[j]); }
for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (dfn[j] > dfn[u] && fe[j] != i) buildcir(u, j, i); } }
LL ans = 0; LL dfs(int u, int fa){ static LL f[N], point[2*N], sc[2*N], q[N]; if (f[u]) return f[u]; LL d1 = 0, d2 = 0; for (int i = h[u]; ~i; i = ne[i]) { if (cir[i]) continue; int j = e[i]; if (j == fa) continue; int d = dfs(j, u) + w[i]; if (d > d1) d2 = d1, d1 = d; elseif (d > d2) d2 = d; } f[u] = d1;
if (u <= n) ans = max(ans, d1+d2); else { int k = 0; // s[k] 递减 for (int i = h[u]; ~i; i = ne[i]) point[k] = e[i], sc[k] = s[e[i]] + stot[e[i]], k++; for (int i = 0; i < k; i++) point[i+k] = point[i], sc[i+k] = s[point[i]]; // circle: max(d[j] + s[j] - s[i] + d[i]) int hh = 0, tt = -1; for (int i = 0; i < k*2; i++) { while (hh <= tt && i - q[hh] >= k) hh++; if (hh <= tt) ans = max(ans, f[point[i]] + f[point[q[hh]]] + sc[q[hh]] - sc[i]); while (hh <= tt && f[point[q[tt]]] + sc[q[tt]] <= f[point[i]] + sc[i]) tt--; q[++tt] = i; } }
return f[u]; }
signedmain(){ memset(h, -1, sizeof h); scanf("%lld", &n); square = n; for (int i = 1, j, l; i <= n; i++) { scanf("%lld%lld", &j, &l); add(i, j, l), add(j, i, l); } for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i, -1); LL res = 0; for (int i = n+1; i <= square; i++) { ans = 0; dfs(i, 0); res += ans; } return !printf("%lld\n", res); }
typedeflonglong LL; constint N = 1000010, M = 2000010; int h[N], e[M], ne[M], w[M], idx; int dfn[N], low[N], timestamp; int fa[N], fe[N]; bool incircle[N]; LL d[N]; int n;
voidadd(int a, int b, int c){ e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; }
LL dfs(int u, int fa, LL& len){ if (d[u]) return d[u]; LL d1 = 0, d2 = 0; for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (j == fa || incircle[j]) continue; LL dist = dfs(j, u, len) + w[i]; if (dist > d1) d2 = d1, d1 = dist; elseif (dist > d2) d2 = dist; } len = max(len, d1+d2); return d[u] = d1; }
voidcircle(int x, int y, int z, LL& len){ static LL s[N*2], dist[N*2], q[N*2]; int sz = 0; LL sum = z;
incircle[x] = true; for (int k = y; k != x; k = fa[k]) s[sz++] = sum, incircle[k] = true, sum += w[fe[k]]; s[sz++] = sum;
sz = 0; for (int k = y; k != x; k = fa[k]) dist[sz++] = dfs(k, 0, len); dist[sz++] = dfs(x, 0, len);
for (int i = 0; i < sz; i++) dist[i+sz] = dist[i], s[i+sz] = s[i]+sum;
int hh = 0, tt = -1; for (int i = 0; i < sz*2; i++) { while (hh <= tt && i - q[hh] >= sz) hh++; // !单调队列取出的时候需要判断非空 if(hh <= tt) len = max(len, dist[q[hh]] - s[q[hh]] + dist[i] + s[i]); while (hh <= tt && dist[q[tt]] - s[q[tt]] <= dist[i] - s[i]) tt--; q[++tt] = i; } }
voidtarjan(int u, int from, LL& len){ dfn[u] = low[u] = ++timestamp;
for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (!dfn[j]) { fe[j] = i, fa[j] = u; tarjan(j, i, len); low[u] = min(low[u], low[j]); } elseif (i != (from ^ 1)) low[u] = min(low[u], dfn[j]); }
for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (dfn[j] > dfn[u] && fe[j] != i) circle(u, j, w[i], len); } }
intmain(){ memset(h, -1, sizeof h); scanf("%d", &n); for (int i = 1, j, k; i <= n; i++) { scanf("%d%d", &j, &k); add(i, j, k), add(j, i, k); } LL ans = 0; for (int i = 1; i <= n; i++) if (!dfn[i]) { LL len = 0; tarjan(i, -1, len); ans += len; }
typedeflonglong LL; constint N = 1000010, M = 2000010; int h[N], e[M], ne[M], p[N], n, idx; int fe[N]; LL f[N][2]; int dfn[N], timestamp; int invalidedge[2]; int invalidp;
voidadd(int a, int b){ e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
voiddfs(int u, int fa){ f[u][0] = 0, f[u][1] = p[u]; if (u == invalidp) f[u][1] = -1e18; for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (j == fa || i == invalidedge[0] || i == invalidedge[1]) continue; dfs(j, u); f[u][0] += max(f[j][0], f[j][1]); f[u][1] += f[j][0]; } }
voidtarjan(int u, LL& res){ dfn[u] = ++timestamp;
for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (!dfn[j]) { fe[j] = i; tarjan(j, res); } }
for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (dfn[j] > dfn[u] && fe[j] != i) { invalidedge[0] = i, invalidedge[1] = i^1; invalidp = -1; dfs(u, 0); res = max(res, f[u][0]); invalidp = j; dfs(u, 0); res = max(res, f[u][1]); } } }
intmain(){ memset(h, -1, sizeof h);
scanf("%d", &n); for (int i = 1, j; i <= n; i++) scanf("%d%d", &p[i], &j), add(i, j), add(j, i);
LL ans = 0; for (int i = 1; i <= n; i++) if (!dfn[i]) { LL res = 0; tarjan(i, res); ans += res; } return !printf("%lld\n", ans); }
[CF1873H] Mad City
Marcel and Valeriu are in the mad city, which is represented by n buildings with n two-way roads between them.
Marcel and Valeriu start at buildings a and b respectively. Marcel wants to catch Valeriu, in other words, be in the same building as him or meet on the same road.
During each move, they choose to go to an adjacent building of their current one or stay in the same building. Because Valeriu knows Marcel so well, Valeriu can predict where Marcel will go in the next move. Valeriu can use this information to make his move. They start and end the move at the same time.
It is guaranteed that any pair of buildings is connected by some path and there is at most one road between any pair of buildings.
Assuming both players play optimally, answer if Valeriu has a strategy to indefinitely escape Marcel.
constint N = 200010, M = 400010; int n, a, b; int h[N], e[M], ne[M], idx; int dfn[N], fa[N], timestamp; bool incircle[N];
voidadd(int a, int b){ e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
voidtarjan(int u){ dfn[u] = ++timestamp; for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (!dfn[j]) { fa[j] = u; tarjan(j); } }
for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (dfn[j] > dfn[u] && fa[j] != u) { incircle[u] = true; for (int k = j; k != u; k = fa[k]) incircle[k] = true; } } }
voidbfs_b(int& p, int& d){ staticint dist[N]; fill(dist, dist+1+n, -1); queue<int> q; q.push(b); dist[b] = 0; while (q.size()) { int t = q.front(); q.pop(); if (incircle[t]) return p = t, d = dist[t], void();
for (int i = h[t]; ~i; i = ne[i]) { int j = e[i]; if (dist[j] != -1) continue; dist[j] = dist[t] + 1; q.push(j); } } }
intbfs_a(int p){ staticint dist[N]; fill(dist, dist+1+n, -1); dist[a] = 0; queue<int> q; q.push(a); while (q.size()) { int t = q.front(); q.pop(); if (t == p) return dist[t];
for (int i = h[t]; ~i; i = ne[i]) { int j = e[i]; if (dist[j] != -1) continue; dist[j] = dist[t] + 1; q.push(j); } } exit(-1); }
#define int long long #define lowbit(x) ((x)&(-x)) constint N = 110010, M = 220010; int h[N], n, q, idx = 2; int fa[N], dep[N], son[N], sz[N], dfn[N], dfnw[N], w[N], top[N], ts;
structEdge { int to, nxt, w; } e[M];
int tr[N]; int rmedge;
voidadd(int a, int b, int c){ e[idx] = {b, h[a], c}, h[a] = idx++; }
voidtarjan(int u, int father){ staticint dfn[N], fa[N], ts; dfn[u] = ++ts, fa[u] = father; for (int i = h[u]; i; i = e[i].nxt) { int to = e[i].to; if (!dfn[to]) tarjan(to, u); }
for (int i = h[u]; i; i = e[i].nxt) { int to = e[i].to; if (dfn[to] > dfn[u] && fa[to] != u) rmedge = i; } }
intquery(int p){ int res = 0; for (; p; p -= lowbit(p)) res += tr[p]; return res; }
intquery(int l, int r){ returnquery(r) - query(l-1); }
voidadd(int p, int x){ for (; p <= n; p += lowbit(p)) tr[p] += x; }
voidmodify(int p, int x){ int raw = query(p, p); add(p, -raw+x); }
int a = e[x<<1].to, b = e[x<<1|1].to; if (dep[a] < dep[b]) swap(a, b); modify(dfn[a], y); }
intlca(int x, int y){ while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); x = fa[top[x]]; } return dep[x] > dep[y] ? y : x; }
intquery_path(int x, int y){ int res = 0; int u = lca(x, y); while (top[x] != top[u]) { res += query(dfn[top[x]], dfn[x]); x = fa[top[x]]; } if (x != u) res += query(dfn[son[u]], dfn[x]);
while (top[y] != top[u]) { res += query(dfn[top[y]], dfn[y]); y = fa[top[y]]; } if (y != u) res += query(dfn[son[u]], dfn[y]);
return res; }
voiddfs1(int u, int father, int weight){ fa[u] = father, dep[u] = dep[father] + 1, sz[u] = 1, w[u] = weight;
for (int i = h[u]; i; i = e[i].nxt) { int to = e[i].to; if (i == rmedge || i == (rmedge ^ 1) || to == father) continue; dfs1(to, u, e[i].w); sz[u] += sz[to]; if (sz[son[u]] < sz[to]) son[u] = to; } }
voiddfs2(int u, int t){ top[u] = t, dfn[u] = ++ts, dfnw[ts] = w[u]; if (!son[u]) return; dfs2(son[u], t);
for (int i = h[u]; i; i = e[i].nxt) { int to = e[i].to; if (i == rmedge || i == (rmedge ^ 1) || to == fa[u] || to == son[u]) continue; dfs2(to, to); } }
signedmain(){ scanf("%lld%lld", &n, &q); for (int i = 1, a, b, c; i <= n; i++) { scanf("%lld%lld%lld", &a, &b, &c); add(a, b, c), add(b, a, c); } tarjan(1, 0); dfs1(1, 0, 0), dfs2(1, 1);
for (int i = 1; i <= n; i++) add(i, dfnw[i]);
for (int i = 1, opt, x, y; i <= q; i++) { scanf("%lld%lld%lld", &opt, &x, &y); if (opt == 1) modify_edge(x, y); else { int res1 = query_path(x, y); int a = e[rmedge].to, b = e[rmedge ^ 1].to; int res2 = query_path(x, a) + query_path(b, y) + e[rmedge].w; int res3 = query_path(x, b) + query_path(a, y) + e[rmedge].w; printf("%lld\n", min(min(res1, res2), res3)); } }
constint N = 100010; int c, t, n, m, val[N], dep[N]; int h[N], col[N], idx = 2; structEdge { int to, nxt, w; } e[N<<1];
voidadd(int a, int b, int c){ e[idx] = {b, h[a], c}, h[a] = idx++; }
intdfs(int u, int co, bool& unk){ int sz = 1; col[u] = co; if (val[u] == UNKNOWN) unk = true;
for (int i = h[u]; i; i = e[i].nxt) { int to = e[i].to, w = e[i].w; int nco = w ? -co : co; if (col[to] && col[to] != nco) unk = true; elseif (!col[to]) sz += dfs(to, nco, unk); } return sz; }
voidsolve(){ scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) dep[i] = i, col[i] = h[i] = 0, val[i] = UNINITIALIZED; idx = 2;
for (int i = 1; i <= n; i++) { if (dep[i] < 0) add(-dep[i], i, 1), add(i, -dep[i], 1); elseadd(dep[i], i, 0), add(i, dep[i], 0); }
int ans = 0; for (int i = 1; i <= n; i++) { if (col[i]) continue; bool unk = false; int sz = dfs(i, 1, unk); if (unk) ans += sz; } printf("%d\n", ans); }
intmain(){ scanf("%d%d", &c, &t); while (t--) solve(); return0; }
constint N = 100010; int c, t, n, m, val[N], fe[N], dep[N]; bool mark[N<<1], ins[N], inc[N], st[N]; int h[N], idx = 2; stack<int> stk; structEdge { int to, nxt, w; } e[N<<1];
voidadd(int a, int b, int c){ e[idx] = {b, h[a], c}, h[a] = idx++; }
intdfs(int u, int f, bool& unk){ int sz = 1; st[u] = true; if (val[u] == UNKNOWN) unk = true;
for (int i = h[u]; i; i = e[i].nxt) { int to = e[i].to, w = e[i].w; if (to == f || inc[to]) continue; sz += dfs(to, u, unk); } return sz; }
boolfindcir(int u, bool& unk, vector<int>& cyc){ ins[u] = true; stk.push(u); for (int i = h[u]; i; i = e[i].nxt) { int to = e[i].to; if (mark[i]) continue;
fe[to] = i; mark[i] = mark[i^1] = true; if (ins[to]) { int y, sum = 0; do { y = stk.top(); stk.pop(); cyc.emplace_back(y); inc[y] = true; sum += e[fe[y]].w; } while (y != to); unk = sum & 1; returntrue; }
for (int i = 1; i <= n; i++) { if (dep[i] < 0) add(-dep[i], i, 1), add(i, -dep[i], 1); elseadd(dep[i], i, 0), add(i, dep[i], 0); } int ans = 0; bool unk = 0, unktot = 0; vector<int> cyc; for (int i = 1; i <= n; i++) { if (st[i]) continue; cyc.clear(); unktot = 0; if (!findcir(i, unktot, cyc)) cyc.emplace_back(i);
for (int c: cyc) { unk = 0; int sz = dfs(c, 0, unk); if (unk || unktot) ans += sz; } }
printf("%d\n", ans); }
intmain(){ scanf("%d%d", &c, &t); while (t--) solve(); return0; }