• 【NOI2014】魔法森林


    题面

    https://www.luogu.org/problem/P2387

    题解

    双关键字讨论处理,直接固定一个关键字枚举第二个即可。

    $LCT$维护边上信息,拆边。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define ri register int
    #define N 50500
    #define M 100500
    
    int n,m;
    int stk[N+M];
    int top,ans;
    
    using namespace std;
    
    struct cut{
      int u,v,a,b;
      bool operator < (const cut& rhs) const {
        return a<rhs.a;
      }
    } e[M];
    
    struct binchaji{
      int f[N];
      void clear() {
        for (ri i=1;i<=n;i++) f[i]=i;
      }
      int findroot(int x) {
        if (f[x]==x) return x;
        return f[x]=findroot(f[x]);
      }
      void merge(int u,int v) {
        f[u]=v;
      }
    } set;
    
    struct link_cut_tree{
      int b[N+M],poi[N+M];
      int f[N+M],ch[N+M][2];
      bool rev[N+M];
      bool opt(int x) {
        return ch[f[x]][1]==x;
      }
      bool notroot(int x) {
        return ch[f[x]][0]==x || ch[f[x]][1]==x;
      }
      void update(int x) {
        poi[x]=x;
        if (ch[x][0] && b[poi[ch[x][0]]]>b[poi[x]]) poi[x]=poi[ch[x][0]];
        if (ch[x][1] && b[poi[ch[x][1]]]>b[poi[x]]) poi[x]=poi[ch[x][1]];
      }
      void rotate(int x) {
        int y=f[x],z=f[y],s=opt(x),w=ch[x][1^s];
        f[x]=z; if (notroot(y)) ch[z][opt(y)]=x;
        ch[y][s]=w; if (w) f[w]=y;
        f[y]=x; ch[x][1^s]=y;
        update(y); update(x);
      }
      void pushr(int x) {
        if (!rev[x]) return;
        rev[x]=0;
        swap(ch[x][0],ch[x][1]);
        if (ch[x][0]) rev[ch[x][0]]^=1;
        if (ch[x][1]) rev[ch[x][1]]^=1;
      }
      void splay(int x) {
        int y=x;
        top=0;
        while (notroot(y)) stk[++top]=y,y=f[y]; stk[++top]=y;
        while (top) pushr(stk[top]),top--;
        while (notroot(x)) {
          if (!notroot(f[x])) rotate(x);
          else {
            if (opt(x)==opt(f[x])) rotate(f[x]); else rotate(x);
            rotate(x);
          }
        }
      }
      
      void access(int x) {
        int y=0;
        while (x) {
          splay(x);
          ch[x][1]=y; update(x);
          y=x; x=f[x];
        }
      }
      
      void makeroot(int x) {
        access(x); splay(x); rev[x]^=1; pushr(x);
      }
      
      void link(int x,int y) {
        makeroot(x);
        f[x]=y;
      }
      void cut(int x,int y) {
        makeroot(x);
        access(y);
        splay(y);
        ch[y][opt(x)]=f[x]=0;
        update(y);
      }
      
      int query(int x,int y) {
        makeroot(x);
        access(y); splay(y);
        return poi[y];
      }
    } lct;
    
    
    void add_edge(int x) {
      lct.link(e[x].u,x+n);
      lct.link(e[x].v,x+n);
    }
    
    void del_edge(int x) {
      lct.cut(e[x].u,x+n);
      lct.cut(e[x].v,x+n);
    }
    
    void update(int cur){
      int p=lct.query(1,n);
      if (lct.b[p]+e[cur].a<ans) ans=lct.b[p]+e[cur].a;
    }
    
    int main(){
      scanf("%d %d",&n,&m);
      for (ri i=1;i<=m;i++) {
        scanf("%d %d %d %d",&e[i].u,&e[i].v,&e[i].a,&e[i].b);
      }
      sort(e+1,e+m+1);
      for (ri i=1;i<=m;i++) {
        lct.b[n+i]=e[i].b;
        lct.poi[n+i]=n+i;
      }
      set.clear();
      ans=987654321;
      
      for (ri i=1;i<=m;i++) if (e[i].u!=e[i].v) {
        int root1=set.findroot(e[i].u),root2=set.findroot(e[i].v);
        if (root1!=root2) {
          set.merge(root1,root2);
          add_edge(i);
          if (set.findroot(1)==set.findroot(n)) update(i);
        }
        else {
          int poi=lct.query(e[i].u,e[i].v);
          if (lct.b[poi]>e[i].b) {
            del_edge(poi-n);
            add_edge(i);
            if (set.findroot(1)==set.findroot(n)) update(i);
          }
        }
      }
      if (ans==987654321) puts("-1"); else cout<<ans<<endl;
    }
  • 相关阅读:
    GC 的认识
    SSRF 攻击技术
    文件包含漏洞
    文件的上传和下载
    XSS
    SQL注入工具 sqlmap
    自动化测试框架
    mac配置环境变量
    pycharm与git想集成 上传下载代码
    测试人员需要掌握的linux基本操作
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11423882.html
Copyright © 2020-2023  润新知