namespace Aeq1 { int arr[maxn]; boolcmp(int a, int b){ return a > b; }
voidsolve(){ for (int i = head[1]; i; i = edges[i].nxt) { int to = edges[i].to; arr[to - 1] = edges[i].val; } sort(arr + 1, arr + n, cmp); ans = inf; for (int i = 1; i <= m; ++i) { ans = min(ans, arr[i] + arr[2 * m - i + 1]); } printf("%d\n", ans); return ; } }
intDfs(int now, int fa){ int res1 = 0, res2 = 0; for (int i = head[now]; i; i = edges[i].nxt) { int to = edges[i].to; if (to == fa) continue; res2 = max(res2, Dfs(to, now) + edges[i].val); if (res2 > res1) swap(res1, res2); } ans = max(ans, res1 + res2); return res1; }
voiddfs(int now, int fa){ for (int i = head[now]; i; i = edges[i].nxt) { int to = edges[i].to; if (to == fa) continue; dfs(to, now); arr[now] = edges[i].val; } }
booljudge(int x){ int t = 0, now = 0; for (int i = 1; i < n; ++i) { if (now + arr[i] >= x) { now = 0; t++; } else { now += arr[i]; } } return t >= m; }
voidsolve(){ dfs(1, 0); Dfs(1, 0); int l = 1, r = ans, mid; while (l < r) { mid = l + r + 1 >> 1; if (judge(mid)) l = mid; else r = mid - 1; } printf("%d\n", l); return ; } }
structEdge { int from, to, val; Edge(int u, int v, int w) : from(u), to(v), val(w) {} }; vector<Edge> G[maxn]; voidadd(int u, int v, int w){ G[u].push_back(Edge(u, v, w)); G[v].push_back(Edge(v, u, w)); }
intdfs(int u, int fa){ priority_queue<int> lh; priority_queue<int, vector<int>, greater<int> > sh; int ln = 0, sn = 1; for (int i = 0; i < G[u].size(); ++i) { if (G[u][i].to != fa) { int d = G[u][i].val + dfs(G[u][i].to, u); sh.push(d); lh.push(d); ln++; } } while (ln > 0 && lh.top() >= mid) {num++; lh.pop(); ln--;} int now = 0; while (ln > sn) { if (u != 1 && lh.top() + sh.top() >= mid) { int cnt = 0; while (ln > sn && lh.top() + sh.top() >= mid) {s[++cnt] = lh.top(); lh.pop(); ln--;} num++; sh.pop(); sn++; while (cnt > 1) {lh.push(s[--cnt]); ln++;} } elseif (u == 1 && lh.top() + sh.top() >= mid) { lh.pop(); sh.pop(); ln--; sn++; num++; } else { now = sh.top(); sh.pop(); sn++; } if (num >= m) break; } if (ln >= sn && !lh.empty()) return lh.top(); elsereturn now; }
boolcheck(){ num = 0; dfs(1, 0); if (num >= m) returntrue; elsereturnfalse; }
intmain(){ read(n); read(m); int all = 0; for (int i = 1; i < n; ++i) { int u, v, w; read(u); read(v); read(w); add(u, v, w); all += w; } int l = 0, r = all / m, ans = 0; while (l <= r) { mid = (l + r) >> 1; if (check()) { l = mid + 1; ans = mid; } else { r = mid - 1; } } printf("%d\n", ans); return0; } /* 1050ms 11964kB with O2 */
namespace SolveOne { int cnt = 0; bool vis[maxn]; voiddfs(int u, int fa){ ans[++cnt] = u; vis[u] = true; for (int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if (!vis[v]) { dfs(v, u); } } } voidsolve(){ for (int i = 1; i <= n; ++i) { sort(G[i].begin(), G[i].end()); } dfs(1, 0); for (int i = 1; i <= n; ++i) { printf("%d ", ans[i]); } } } /* 1050ms 11964kB with O2 */
$II.$ $m = n$
存在一个环(基环树) 手算一下样例2可以发现,有且仅有一条边不会通过 逐个删边尝试即可,删边后和$m = n - 1$相同 样例2图示:
inlineintread(){ int x = 0, f = 1; char ch = getchar(); while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();} while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();} return x * f; }
int n, m, ans[maxn], in[maxn][2];
vector<int> G[maxn];
namespace SolveOne { int cnt = 0; bool vis[maxn]; voiddfs(int u, int fa){ ans[++cnt] = u; vis[u] = true; for (int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if (!vis[v]) { dfs(v, u); } } } voidsolve(){ for (int i = 1; i <= n; ++i) { sort(G[i].begin(), G[i].end()); } dfs(1, 0); for (int i = 1; i <= n; ++i) { printf("%d ", ans[i]); } } }
namespace SolveTwo { int cnt = 0, res[maxn], du, dv; bool vis[maxn]; boolnotdel(int u, int v){ //判断该边是否被删 if ((u == du && v == dv) || (u == dv && v == du)) { returnfalse; } returntrue; } voiddfs(int u, int fa){ res[++cnt] = u; vis[u] = true; for (int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if (!vis[v] && notdel(u, v)) { dfs(v, u); } } } booljudge(){ //判断是否为更优情况 for (int i = 1; i <= n; ++i) { if (ans[i] != res[i]) { return ans[i] > res[i]; } } returnfalse; } voidsolve(){ memset(ans, 0x3f, sizeof(ans)); for (int i = 1; i <= n; ++i) { sort(G[i].begin(), G[i].end()); } for (int i = 1; i <= m; ++i) { cnt = 0; memset(res, 0, sizeof(res)); memset(vis, 0, sizeof(vis)); du = in[i][0]; //删边 dv = in[i][1]; dfs(1, 0); if (judge() && cnt == n) { //如果更优则更改ans[] memcpy(ans, res, sizeof(res)); } } for (int i = 1; i <= n; ++i) { printf("%d ", ans[i]); } } }
intmain(){ n = read(); m = read(); for (int i = 1; i <= m; ++i) { int u = read(), v = read(); G[u].push_back(v); G[v].push_back(u); in[i][0] = u; //存储输入信息 in[i][1] = v; } if (m == n - 1) { SolveOne::solve(); } else { SolveTwo::solve(); } return0; } /* 2244ms 1276kB */