Submission #330257

#TimeUsernameProblemLanguageResultExecution timeMemory
330257cki86201Mountains and Valleys (CCO20_day1problem3)C++17
25 / 25
4391 ms201944 KiB
#include <bits/stdc++.h> using namespace std; #define Fi first #define Se second typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; #define all(x) (x).begin(), (x).end() #define pb push_back #define szz(x) (int)(x).size() #define rep(i, n) for(int i=0;i<(n);i++) typedef tuple<int, int, int> t3; const int ADD = 1<<19, INF = 1e9; struct node { int pv, mv, cv, val; void init(int x, int d, int d2) { pv = d + x, mv = d - x, cv = d2; val = -INF; } node operator+(const node &R) const { node res; res.pv = max(pv, R.pv); res.mv = max(mv, R.mv); res.cv = max(cv, R.cv); res.val = max({val, R.val, pv + R.mv}); return res; } } T[1<<20]; void init(int x, int d, int d2) { T[ADD+x].init(x, d, d2); for(int r=(ADD+x)/2;r;r>>=1) { T[r] = T[r*2] + T[r*2+1]; } } int lvt[100], rvt[100]; node read(int l, int r) { if(l > r) { node res; res.init(0, -INF, -INF); return res; } l += ADD, r += ADD; int lt = 0, rt = 0; while(l <= r) { if(l & 1) lvt[lt++] = l++; if(!(r & 1)) rvt[rt++] = r--; l >>= 1, r >>= 1; } while(rt) lvt[lt++] = rvt[--rt]; node res = T[lvt[0]]; for(int i=1;i<lt;i++) res = res + T[lvt[i]]; return res; } int N, M; vector <int> E[500050]; vector <t3> AE; int dis[500050], pre[500050]; int far(int x) { memset(dis, -1, sizeof dis); vector <int> q; auto ins_q = [&](int x, int d, int p) { if(dis[x] == -1) q.pb(x), dis[x] = d, pre[x] = p; }; ins_q(x, 0, -1); rep(i, szz(q)) { int t = q[i]; for(int e : E[t]) ins_q(e, dis[t] + 1, t); } return q.back(); } int fd[500050], dep[500050], up[500050][20], mxd[500050], dv[500050]; vector <pii> chd[500050], dvl[500050]; int get_l(vector <pii> &h, int d, int e = -1) { int res = 0, rc = 0; for(auto &[l, y] : h) if(y != e) { ++rc; res += l; if(rc == d) return res; } return res; } int DL[500050][2]; void pdfs(int x) { for(int e : E[x]) if(fd[e] == -1) { fd[e] = fd[x]; dep[e] = dep[x] + 1; up[e][0] = x; for(int i=1;i<20;i++) up[e][i] = up[ up[e][i-1] ][i-1]; pdfs(e); mxd[x] = max(mxd[x], mxd[e] + 1); dv[x] = max(dv[x], dv[e]); chd[x].pb({mxd[e]+1, e}); dvl[x].pb({dv[e], e}); } sort(all(chd[x]), greater<>()); sort(all(dvl[x]), greater<>()); dv[x] = max(dv[x], get_l(chd[x], 2, -1)); } int get_lca(int x, int y) { if(dep[x] < dep[y]) swap(x, y); rep(i, 20) if(1<<i & (dep[x] - dep[y])) x = up[x][i]; for(int i=19;i>=0;i--) if(up[x][i] != up[y][i]) x = up[x][i], y = up[y][i]; return x == y ? x : up[x][0]; } int climb(int x, int d) { rep(i, 20) if(1<<i & d) x = up[x][i]; return x; } void qdfs(int x, int u = 0, int h = 0, int fa = -1) { DL[x][1] = max(dv[x], h); for(int e : E[x]) if(fd[e] == fd[x] && e != fa) { int du = 0, dh = max({h, get_l(dvl[x], 1, e), get_l(chd[x], 2, e)}); if(fa != -1) du = max(u, get_l(chd[x], 1, e)) + 1; DL[e][0] = max(du, mxd[e]); qdfs(e, du, dh, x); } } int main() { scanf("%d%d", &N, &M); rep(i, M) { int x, y, z; scanf("%d%d%d", &x, &y, &z); ++x; ++y; if(z == 1) { E[x].pb(y); E[y].pb(x); } else AE.pb({x, y, z}); } int l = far(1); int r = far(l); int ans = 2 * (N - 1) - dis[r], lend = dis[r]; vector <int> Dia; for(int t=r;t!=-1;t=pre[t]) Dia.pb(t); reverse(all(Dia)); memset(fd, -1, sizeof fd); rep(i, szz(Dia)) fd[Dia[i]] = i; for(int e : Dia) pdfs(e); for(int e : Dia) DL[e][0] = -INF, qdfs(e); int m = szz(Dia); rep(i, m) init(i, mxd[Dia[i]], dv[Dia[i]]); for(auto [x, y, d] : AE) { if(fd[x] > fd[y]) swap(x, y); if(fd[x] == fd[y]) { int lca = get_lca(x, y); int c = dep[x] + dep[y] - 2 * dep[lca]; ans = min(ans, 2 * N - 2 + d - c - lend); } else { int fx = fd[x], fy = fd[y], rx = Dia[fx], ry = Dia[fy]; node n1 = read(0, fx-1), n2 = read(fx+1, fy-1), n3 = read(fy+1, m-1); int max_d2 = max({DL[x][1], DL[y][1], n1.pv, n2.cv, n3.mv+(m-1)}); int cx = (dep[x] ? climb(x, dep[x]-1) : -1); int cy = (dep[y] ? climb(y, dep[y]-1) : -1); max_d2 = max({max_d2, fx + get_l(chd[rx], 1, cx), m-1-fy + get_l(chd[ry], 1, cy)}); int c = fy - fx + dep[x] + dep[y]; ans = min(ans, 2 * N - 2 + d - c - max_d2); int max_d1 = max(DL[x][0] + max(fy, m-1-fy) + dep[y], DL[y][0] + max(fx, m-1-fx) + dep[x]); max_d1 = max(max_d1, fx + dep[x] + (m-1-fy) + dep[y]); max_d1 = max(max_d1, fx + dep[x] + n2.mv + fy + dep[y]); max_d1 = max(max_d1, dep[x] + n2.pv - fx + (m-1-fy) + dep[y]); max_d1 = max(max_d1, n2.val + fy - fx + dep[x] + dep[y]); ans = min(ans, 2 * N - 4 + d - max_d1); } } printf("%d\n", ans); return 0; }

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:127:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  127 |  scanf("%d%d", &N, &M);
      |  ~~~~~^~~~~~~~~~~~~~~~
Main.cpp:130:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  130 |   scanf("%d%d%d", &x, &y, &z); ++x; ++y;
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...