EntropyIncreaser

NOI2014 魔法森林

Mar 23rd, 2018
337
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.85 KB | None | 0 0
  1. #include <cstdio>
  2.  
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. struct Data {
  8.     int v, id;
  9.  
  10.     Data() {}
  11.  
  12.     Data(int v, int id) : v(v), id(id) {}
  13.  
  14.     bool operator<(const Data& x) const
  15.     { return v < x.v; }
  16. };
  17.  
  18. const int N = 150010;
  19.  
  20. struct LinkCutTree {
  21.     struct Node {
  22.         bool rev;
  23.         Data v, mex;
  24.         union {
  25.             struct {
  26.                 Node *ls, *rs;
  27.             };
  28.             Node* ch[2];
  29.         };
  30.         Node *prt, *path;
  31.  
  32.         bool relation() const
  33.         { return this == prt->rs; }
  34.  
  35.         void pushDown() {
  36.             if (rev) {
  37.                 rev = false;
  38.                 swap(ls, rs);
  39.                 if (ls)
  40.                     ls->rev = !ls->rev;
  41.                 if (rs)
  42.                     rs->rev = !rs->rev;
  43.             }
  44.         }
  45.  
  46.         void update() {
  47.             mex = v;
  48.             if (ls)
  49.                 mex = max(mex, ls->mex);
  50.             if (rs)
  51.                 mex = max(mex, rs->mex);
  52.         }
  53.  
  54.         void rotate() {
  55.             if (prt->prt)
  56.                 prt->prt->pushDown();
  57.             prt->pushDown();
  58.             pushDown();
  59.             path = prt->path;
  60.             prt->path = NULL;
  61.             Node* p = prt;
  62.             bool f = relation();
  63.             if (p->prt)
  64.                 p->prt->ch[p->relation()] = this;
  65.             prt = p->prt;
  66.             p->ch[f] = ch[!f];
  67.             if (ch[!f])
  68.                 ch[!f]->prt = p;
  69.             ch[!f] = p;
  70.             p->prt = this;
  71.             p->update();
  72.             update();
  73.         }
  74.  
  75.         void splay() {
  76.             while (prt) {
  77.                 if (!prt->prt)
  78.                     return rotate();
  79.                 prt->prt->pushDown();
  80.                 prt->pushDown();
  81.                 if (relation() == prt->relation()) {
  82.                     prt->rotate();
  83.                     rotate();
  84.                 } else {
  85.                     rotate();
  86.                     rotate();
  87.                 }
  88.             }
  89.         }
  90.  
  91.         void expose() {
  92.             splay();
  93.             pushDown();
  94.             if (rs) {
  95.                 rs->path = this;
  96.                 rs->prt = NULL;
  97.                 rs = NULL;
  98.                 update();
  99.             }
  100.         }
  101.  
  102.         bool splice() {
  103.             splay();
  104.             if (!path)
  105.                 return false;
  106.             path->expose();
  107.             path->rs = this;
  108.             prt = path;
  109.             path = NULL;
  110.             prt->update();
  111.             return true;
  112.         }
  113.  
  114.         void access() {
  115.             expose();
  116.             while (splice());
  117.         }
  118.  
  119.         void evert() {
  120.             access();
  121.             splay();
  122.             rev = !rev;
  123.         }
  124.  
  125.         Data query() {
  126.             access();
  127.             splay();
  128.             return mex;
  129.         }
  130.  
  131.         Node* find() {
  132.             access();
  133.             splay();
  134.             Node* p = this;
  135.             while (p->pushDown(), p->ls)
  136.                 p = p->ls;
  137.             p->splay();
  138.             return p;
  139.         }
  140.     };
  141.  
  142.     Node ver[N];
  143.  
  144.     void link(int u, int v) {
  145. //      fprintf(stderr, "LINK %d %d\n", u, v);
  146.         ver[u].evert();
  147.         ver[u].path = ver + v;
  148.     }
  149.  
  150.     void cut(int u, int v) {
  151. //      fprintf(stderr, "CUT %d %d\n", u, v);
  152.         ver[u].evert();
  153.         ver[v].access();
  154.         ver[u].expose();
  155. //      fprintf(stderr, "%p\n", ver[v].path);
  156.         ver[v].path = NULL;
  157.     }
  158.  
  159.     bool connected(int u, int v) {
  160.         return ver[u].find() == ver[v].find();
  161.     }
  162.  
  163.     Data query(int u, int v) {
  164.         ver[u].evert();
  165. //      fprintf(stderr, "Q %d\n", ver[v].query().v);
  166.         return ver[v].query();
  167.     }
  168. };
  169.  
  170. int n;
  171. int eu[N], ev[N];
  172.  
  173. struct DynamicMST {
  174.     int sum, ecnt;
  175.     LinkCutTree tree;
  176.  
  177.     void add(int u, int v, int w) {
  178.         ++ecnt;
  179.         eu[ecnt] = u;
  180.         ev[ecnt] = v;
  181.         tree.ver[n + ecnt].v = tree.ver[n + ecnt].mex = Data(w, ecnt);
  182.         if (!tree.connected(u, v)) {
  183.             tree.link(n + ecnt, u);
  184.             tree.link(n + ecnt, v);
  185.             sum += w;
  186.             return;
  187.         }
  188.         Data mex = tree.query(u, v);
  189. //      fprintf(stderr, "Q %d %d %d\n", mex.v, w, mex.id);
  190.         if (mex.v <= w)
  191.             return;
  192.         sum -= mex.v;
  193.         tree.cut(n + mex.id, eu[mex.id]);
  194.         tree.cut(n + mex.id, ev[mex.id]);
  195.         tree.link(n + ecnt, u);
  196.         tree.link(n + ecnt, v);
  197.         sum += w;
  198.     }
  199. };
  200.  
  201. struct Edge {
  202.     int u, v, a, b;
  203.  
  204.     bool operator<(const Edge& x) const {
  205.         return a < x.a;
  206.     }
  207. };
  208.  
  209. DynamicMST mst;
  210.  
  211. int m;
  212. Edge e[N];
  213.  
  214. int main() {
  215.     scanf("%d%d", &n, &m);
  216.     for (int i = 1; i <= m; ++i) {
  217.         scanf("%d%d%d%d", &e[i].u, &e[i].v, &e[i].a, &e[i].b);
  218.     }
  219.     int ans = -1;
  220.     sort(e + 1, e + m + 1);
  221.     for (int i = 1; i <= m; ++i) {
  222.         mst.add(e[i].u, e[i].v, e[i].b);
  223.         if (mst.tree.connected(1, n)) {
  224.             Data cur = mst.tree.query(1, n);
  225.             if ((ans == -1 || cur.v + e[i].a < ans)) {
  226. //              fprintf(stderr, "%d %d\n", i, cur.v);
  227.                 ans = cur.v + e[i].a;
  228.             }
  229.         }
  230.     }
  231.     printf("%d\n", ans);
  232.     return 0;
  233. }
Advertisement
Add Comment
Please, Sign In to add comment