zoukankan      html  css  js  c++  java
  • COJ500 杨老师的路径规划(MST) (我是认真的)

    用LCT来维护生成树,动态加边(s,t,w)时,新建节点x,权值为边权w。

    1.若s与t不连通,则连接s-x,x-t,答案+w

    2.若s与t连通,找出s-t路径上的最大权w2,若w<w2,删除w2的连边,连接s-x,x-t,答案+w-w2

    太水了是不是!

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define lc ch[x][0]
    #define rc ch[x][1]
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=10010;
    int ch[maxn][2],fa[maxn],pre[maxn],flip[maxn],mx[maxn],v[maxn];
    void maintain(int x)
    {
        mx[x]=x;
        if(v[mx[lc]]>v[mx[x]]) mx[x]=mx[lc];
        if(v[mx[rc]]>v[mx[x]]) mx[x]=mx[rc];
    }
    void pushdown(int x)
    {
        if(!flip[x]) return;
        swap(lc,rc);flip[lc]^=1;flip[rc]^=1;flip[x]=0;
    }
    void rotate(int x)
    {
        int y=pre[x],z=pre[y],d=ch[y][0]==x;
        ch[y][d^1]=ch[x][d];pre[ch[x][d]]=y;
        ch[z][ch[z][1]==y]=x;pre[x]=z;
        ch[x][d]=y;pre[y]=x;maintain(y);
    }
    int q[maxn],top;
    void splay(int x)
    {
        for(int i=x;i;i=pre[i]) q[++top]=i;
        if(top!=1) fa[x]=fa[q[top]];
        while(top) pushdown(q[top--]);
        while(pre[x]) rotate(x);
        maintain(x);
    }
    void access(int x)
    {
        for(int y=0;x;x=fa[x])
        {
            splay(x);pre[ch[x][1]]=0;fa[ch[x][1]]=x;
            ch[x][1]=y;pre[y]=x;
            maintain(y=x);
        }
    }
    void makeroot(int x) {access(x);splay(x);flip[x]^=1;}
    void link(int x,int y) {makeroot(x);fa[x]=y;}
    void cut(int x,int y) {makeroot(x);access(y);splay(y);ch[y][0]=pre[ch[y][0]]=0;maintain(x);}
    int find(int x) {access(x);splay(x);while(ch[x][0]) x=ch[x][0];return x;}
    int query(int x,int y)
    {
        makeroot(x);access(y);splay(y);return mx[y];
    }
    int s[maxn],t[maxn];
    int main()
    {
        int n=read(),m=n*(n-1)>>1,ToT=n,ret=0;
        for(int i=1;i<=m;i++)
        {
            s[i]=read(),t[i]=read(),v[++ToT]=read();
            if(find(s[i])!=find(t[i])) link(s[i],ToT),link(ToT,t[i]),ret+=v[ToT];
            else
            {
                int p=query(s[i],t[i]);if(v[p]>v[ToT])
                {
                    ret+=v[ToT]-v[p];
                    cut(p,s[p-n]);cut(p,t[p-n]);
                    link(s[i],ToT);link(ToT,t[i]);
                }
            }
        }
        printf("%d
    ",ret);
        return 0;
    }
    View Code
  • 相关阅读:
    《京东峰值系统设计》读后感
    《王者荣耀游戏服务器架构演进(完整版)》读后感
    《秒杀系统架构分析与实战》读后感
    《阿里如何实现秒级百万TPS?搜索离线大数据平台架构解读》读后感
    《阿里游戏高可用架构设计实践》读后感
    Spark SQL 编程初级实践
    系统质量属性之——性能
    《信息技术手册查重错误比对分析》开发记录7
    《信息技术手册查重错误比对分析》开发记录6
    【Codeforces Round #589 (Div. 2) D】Complete Tripartite
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4590667.html
Copyright © 2011-2022 走看看