「CF1023F」Mobile Phone Network
标签:
「CF1023F」Mobile Phone Network传送门
直接钦定那 \(k\) 条边在最小生成树中,,然后把最小生成树树剖一下。
每条其它边的效果就是把该边端点路径上的边的权对该边边权取 \(\min\)。
不会区间取 \(\min\) 的看这里。
参考代码:
#include <algorithm> #include <cstdio> #define rg register #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout) using namespace std; template < class T > inline void read(T& s) { s = 0; int f = 0; char c = getchar(); while ('0' > c || c > '9') f |= c == '-', c = getchar(); while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar(); s = f ? -s : s; } typedef long long LL; const int _ = 5e5 + 5, __ = 1e6 + 5, INF = 2e9; int tot, head[_], nxt[_ << 1], ver[_ << 1], w[_ << 1]; inline void Add_edge(int u, int v, int d) { nxt[++tot] = head[u], head[u] = tot, ver[tot] = v, w[tot] = d; } int n, k, m, tag[_], Fa[_], X[__], Y[__], V[__], vis[__]; int dep[_], siz[_], son[_], fa[_], top[_], rev[_], dfn[_], mn[_ << 2]; inline int Find(int x) { return Fa[x] == x ? x : Fa[x] = Find(Fa[x]); } inline void merge(int x, int y) { Fa[Find(x)] = Find(y); } inline int lc(int p) { return p << 1; } inline int rc(int p) { return p << 1 | 1; } inline void f(int p, int v) { mn[p] = min(mn[p], v); } inline void pushdown(int p) { f(lc(p), mn[p]), f(rc(p), mn[p]), mn[p] = INF; } inline void build(int p = 1, int l = 1, int r = n) { mn[p] = INF; if (l == r) { mn[p] = tag[rev[l]]; return ; } int mid = (l + r) >> 1; build(lc(p), l, mid), build(rc(p), mid + 1, r); } inline void update(int ql, int qr, int v, int p = 1, int l = 1, int r = n) { if (ql <= l && r <= qr) return f(p, v); int mid = (l + r) >> 1; pushdown(p); if (ql <= mid) update(ql, qr, v, lc(p), l, mid); if (qr > mid) update(ql, qr, v, rc(p), mid + 1, r); } inline int query(int id, int p = 1, int l = 1, int r = n) { if (l == r) return mn[p]; int mid = (l + r) >> 1, res; pushdown(p); if (id <= mid) res = query(id, lc(p), l, mid); else res = query(id, rc(p), mid + 1, r); return res; } inline void dfs(int u, int f) { dep[u] = dep[f] + 1, siz[u] = 1, fa[u] = f; for (rg int i = head[u]; i; i = nxt[i]) { int v = ver[i]; if (v == f) continue ; tag[v] = w[i]; dfs(v, u), siz[u] += siz[v]; if (siz[son[u]] < siz[v]) son[u] = v; } } inline void dfs(int u, int f, int topf) { top[rev[dfn[u] = ++dfn[0]] = u] = topf; if (son[u]) dfs(son[u], u, topf); for (rg int i = head[u]; i; i = nxt[i]) { int v = ver[i]; if (v == f || v == son[u]) continue ; dfs(v, u, v); } } inline void uptChain(int x, int y, int v) { int fx = top[x], fy = top[y]; while (fx != fy) { if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy); update(dfn[fx], dfn[x], v), x = fa[fx], fx = top[x]; } if (dep[x] > dep[y]) swap(x, y); update(dfn[x] + 1, dfn[y], v); } int main() { #ifndef ONLINE_JUDGE file("cpp"); #endif read(n), read(k), read(m); for (rg int i = 1; i <= n; ++i) Fa[i] = i; for (rg int u, v, i = 1; i <= k; ++i) read(u), read(v), merge(u, v), Add_edge(u, v, INF), Add_edge(v, u, INF); for (rg int i = 1; i <= m; ++i) { read(X[i]), read(Y[i]), read(V[i]); if (Find(X[i]) != Find(Y[i])) { vis[i] = 1, merge(X[i], Y[i]); Add_edge(X[i], Y[i], 0), Add_edge(Y[i], X[i], 0); } } dfs(1, 0), dfs(1, 0, 1), build(); for (rg int i = 1; i <= m; ++i) if (!vis[i]) uptChain(X[i], Y[i], V[i]); LL ans = 0; for (rg int i = 2; i <= n; ++i) { int res = query(i); if (res == INF) return puts("-1"), 0; else ans += res; } printf("%lld\n", ans); return 0; }「CF1023F」Mobile Phone Network
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/31029.html
- 上一篇: 这里主要是说使用JS和JQ获取a标签的href网址
- 下一篇: 各个浏览器中的弹窗名都不同