NOI模拟(10.29)T1 管道

来源:互联网 发布:人生七年 知乎 编辑:程序博客网 时间:2024/06/06 10:38

管道

题目背景:

10.29 NOI模拟T1

分析:倍增 or lctor 链剖 + 线段树 or 链剖 + st or···

 

我终于明白了,先入为主是在作死······拿到这道题,第一反应最小生成树,然后要改边,这个不是lct裸题吗,然后一发lct就上去了······然后后来才听说,貌似这个题把最小生成树建出来是不是就很稳了······不管链剖或者倍增好像都能直接找到路径最大值····然后check一下就好了·····最后只好安慰自己复杂度是一样的······最后还是跑过去了,最慢的点0.92s····

Source:

/*created by scarlyw*/#include <cstdio>#include <string>#include <algorithm>#include <cstring>#include <iostream>#include <cmath>#include <cctype>#include <vector>#include <set>#include <queue>#include <ctime>inline char read() {static const int IN_LEN = 1024 * 1024;static char buf[IN_LEN], *s, *t;if (s == t) {t = (s = buf) + fread(buf, 1, IN_LEN, stdin);if (s == t) return -1;}return *s++;}///*template<class T>inline void R(T &x) {static char c;static bool iosig;for (c = read(), iosig = false; !isdigit(c); c = read()) {if (c == -1) return ;if (c == '-') iosig = true;}for (x = 0; isdigit(c); c = read()) x = ((x << 2) + x << 1) + (c ^ '0');if (iosig) x = -x;}//*/const int OUT_LEN = 1024 * 1024;char obuf[OUT_LEN], *oh = obuf;inline void write_char(char c) {if (oh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), oh = obuf;*oh++ = c;}template<class T>inline void W(T x) {static int buf[30], cnt;if (x == 0) write_char('0');else {if (x < 0) write_char('-'), x = -x;for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48;while (cnt) write_char(buf[cnt--]);}}inline void flush() {fwrite(obuf, 1, oh - obuf, stdout);}/*template<class T>inline void R(T &x) {static char c;static bool iosig;for (c = getchar(), iosig = false; !isdigit(c); c = getchar())if (c == '-') iosig = true;for (x = 0; isdigit(c); c = getchar()) x = ((x << 2) + x << 1) + (c ^ '0');if (iosig) x = -x;}//*/const int MAXN = 500000 + 10;struct edges {int u, v, w, id;edges(int u = 0, int v = 0, int w = 0, int id = 0) : u(u), v(v), w(w), id(id) {}inline bool operator < (const edges &a) const {return w < a.w;}} e[MAXN];int w[MAXN], ans[MAXN];struct node *null;struct node {node *c[2], *fa, *pa;bool rev;int max, val;node(int val = 0) : fa(null), pa(null), rev(false), max(val), val(val) {c[0] = c[1] = null;}inline int relation() {return (this == fa->c[1]);}inline void reverse() {if (this == null) return ;rev ^= 1, std::swap(c[0], c[1]);}inline void push_down() {if (this == null) return ;if (rev) c[0]->reverse(), c[1]->reverse(), rev ^= 1;}inline void maintain() {if (this == null) return ;max = val;if (w[c[0]->max] > w[max]) max = c[0]->max;if (w[c[1]->max] > w[max]) max = c[1]->max;}inline void rotate() {push_down();pa = fa->pa, fa->pa = null;node *old_fa = fa;int x = relation();if (old_fa->fa != null) old_fa->fa->c[old_fa->relation()] = this;old_fa->c[x] = c[x ^ 1], fa = old_fa->fa;if (c[x ^ 1] != null) c[x ^ 1]->fa = old_fa;c[x ^ 1] = old_fa, old_fa->fa = this, old_fa->maintain(), maintain();}inline void splay(node *target = null) {while (fa != target) {fa->fa->push_down(), fa->push_down();if (fa->fa == target) fa->push_down(), rotate();else if (fa->relation() == relation()) fa->rotate(), rotate();else rotate(), rotate();}push_down();}inline void expose() {splay();if (c[1] != null) c[1]->fa = null, c[1]->pa = this, c[1] = null, maintain();}inline bool splice() {expose();if (pa == null) return false;pa->expose(), pa->c[1] = this, fa = pa, pa = null, fa->maintain();return true;}inline void access() {expose();while (splice());splay();}inline void evert() {access(), reverse();}} point[MAXN];inline void link(node *u, node *v) {u->evert(), u->pa = v;}inline void cut(node *u, node *v) {u->evert(), v->access(), v->c[0] = null, u->fa = null, v->maintain();}inline node *find_root(node *u) {u->evert();for (; u->push_down(), u->c[0] != null; u = u->c[0]);return u->splay(), u;}inline int query_max(node *u, node *v) {return u->evert(), v->access(), v->max;}int n, m;inline void read_in() {R(n), R(m);for (int i = 1; i <= m; ++i) R(e[i].u), R(e[i].v), R(e[i].w), e[i].id = i, w[i] = e[i].w;}int father[MAXN];inline int get_father(int x) {return (father[x] == x) ? x : (father[x] = get_father(father[x])); }inline void solve() {long long mst = 0;std::sort(e + 1, e + m + 1);null = &point[0], null->c[0] = null->c[1] = null->pa = null->fa = null;null->val = null->max = 0;for (int i = 1; i <= n; ++i) father[i] = i, point[i] = node(0);for (int i = 1; i <= m; ++i) {point[i + n] = node(e[i].id);int u = e[i].u, v = e[i].v, fa1 = get_father(u), fa2 = get_father(v);if (fa1 != fa2) {mst += e[i].w, ans[e[i].id] = 0, father[fa1] = fa2;link(&point[u], &point[i + n]), link(&point[v], &point[i + n]);} else ans[e[i].id] = e[i].w - w[query_max(&point[u], &point[v])];}for (int i = 1; i <= m; ++i) W(mst + (long long)ans[i]), write_char('\n');}int main() {//freopen("pipe.in", "r", stdin);//freopen("pipe.out", "w", stdout);read_in();solve();flush();return 0;}

原创粉丝点击