• 【XSY2187】【HDU2460】Network


    题目大意:

    给你一个无向连通图,再给出一些添边操作,询问每次添边操作之后图中还剩下多少桥。


    思路:

    考虑求出任意一棵生成树

    若连接((u,v)),则生成树上u到v的路径上都不是桥

    设一条边的边权为这条边是不是桥,是则为1,反之则为0

    用树链剖分维护每一条边权,发现只能维护点权

    WDNMD

    考虑化边权为点权,设点(i)的权值为边((i,fa[i]))的权值

    每一次修改把两个点的LCA特判一下,不要修改就行了


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N=100010;
    const int M=200010;
    
    inline void read(int &x) {
        x=0;
        int f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {
            if (ch=='-') {
                f=-1;
            }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        }
        x*=f;
    }
    
    //*****MST部分*****//
    struct note {
        int t;
        int next;
    };
    
    int cnt;
    int head[N];
    note e[M<<1];
    
    struct edge {
        int x;
        int y;
    };
    
    int con;
    edge E[M];
    int f[N];
    int vis[M];
    int n,m,q;
    
    inline void add(int x,int y) {
        e[++cnt].t=y;
        e[cnt].next=head[x];
        head[x]=cnt;
    }
    
    int find(int x) {
        return x==f[x]?x:f[x]=find(f[x]);
    }
    
    inline bool check(int x,int y) {
        int fx=find(x),fy=find(y);
        if (fx==fy) {
            return 0;
        } else {
            f[fx]=f[y];
            return 1;
        }
    }
    
    inline void bulid_MST() {
        for(int i=1;i<=n;i++) {
            f[i]=i;
        }
        for(int i=1;i<=m;i++) {
            if (check(E[i].x,E[i].y)) {
                con++;
                add(E[i].x,E[i].y);
                add(E[i].y,E[i].x);
                vis[i]=1;
            }
            if (con==n-1) {
                break;
            }
        }
    }
    
    //------------------------//
    
    //*****线段树部分*****//
    struct seqt {
        int ls;
        int rs;
        int val;
        int f;
        seqt() {
            ls=rs=val=0;
            f=-1;
        }
    };
    
    seqt node[N<<2];
    int siz;
    int rt;
    
    inline void update(int o) {
        node[o].val=node[node[o].ls].val+node[node[o].rs].val;
    }
    
    inline void down(int o,int l,int r) {
        int mid=(l+r)>>1;
        node[node[o].ls].val=node[o].f*(mid-l+1);
        node[node[o].rs].val=node[o].f*(r-mid);
        node[node[o].ls].f=node[node[o].rs].f=node[o].f;
        node[o].f=-1;
    }
    
    void build(int &o,int l,int r) {
        o=++siz;
        node[o].f=-1;
        if (l==r) {
            node[o].val=1;
            return;
        }
        int mid=(l+r)>>1;
        build(node[o].ls,l,mid);
        build(node[o].rs,mid+1,r);
        update(o);
    }
    
    void change(int o,int l,int r,int L,int R,int val) {
        if (L<=l&&r<=R) {
            node[o].val=val*(r-l+1);
            node[o].f=val;
            return;
        }
        if (node[o].f!=-1) {
            down(o,l,r);
        }
        int mid=(l+r)>>1;
        if (L<=mid) {
            change(node[o].ls,l,mid,L,R,val);
        }
        if (mid<R) {
            change(node[o].rs,mid+1,r,L,R,val);
        }
        update(o);
    }
    
    int query(int o,int l,int r,int L,int R) {
        if (L<=l&&r<=R) {
            return node[o].val;
        }
        if (node[o].f!=-1) {
            down(o,l,r);
        }
        int mid=(l+r)>>1;
        int ans=0;
        if (L<=mid) {
            ans+=query(node[o].ls,l,mid,L,R);
        }
        if (mid<R) {
            ans+=query(node[o].rs,mid+1,r,L,R);
        }
        return ans;
    }
    //------------------------//
    
    //*****树链剖分部分*****//
    int tot;
    int son[N],top[N],dep[N],fa[N],dfn[N],val[N];
    
    void dfs1(int p,int fat) {
        dep[p]=dep[fat]+1;
        fa[p]=fat;
        val[p]=1;
        int max_son=-1;
        for(int i=head[p];i+1;i=e[i].next) {
            int t=e[i].t;
            if (t==fat) {
                continue;
            }
            dfs1(t,p);
            val[p]+=val[t];
            if (val[t]>max_son) {
                son[p]=t;
                max_son=val[t];
            }
        }
    }
    
    void dfs2(int p,int top_p) {
        dfn[p]=++tot;
        top[p]=top_p;
        if (!son[p]) {
            return;
        }
        dfs2(son[p],top_p);
        for(int i=head[p];i+1;i=e[i].next) {
            int t=e[i].t;
            if (t==fa[p]||t==son[p]) {
                continue;
            }
            dfs2(t,t);
        }
    }
    
    int query_tree(int x) {
        return query(rt,1,n,dfn[x],dfn[x]+val[x]-1);
    }
    
    void change_range(int x,int y,int val) {
        while(top[x]!=top[y]) {
            if (dep[top[x]]<dep[top[y]]) {
                swap(x,y);
            }
            change(rt,1,n,dfn[top[x]],dfn[x],val);
            x=fa[top[x]];
        }
        if (dep[x]>dep[y]) {
            swap(x,y);
        }
        change(rt,1,n,dfn[x]+1,dfn[y],val);
    }
    //------------------------/
    
    inline void init() {
        memset(head,-1,sizeof(head));
        memset(e,0,sizeof(e));
        memset(son,0,sizeof(son));
        memset(vis,0,sizeof(vis));
        memset(node,0,sizeof(node));
        cnt=tot=siz=con=0;
    }
    
    int main() {
        int papapa=0;
        read(n),read(m);
        while(n&&m) {
            init();
            for(int i=1;i<=m;i++) {
                read(E[i].x),read(E[i].y);
            }
            bulid_MST();
            dfs1(1,1);
            dfs2(1,1);
            build(rt,1,n);
            for(int i=1;i<=m;i++) {
                if (!vis[i]) {
                    change_range(E[i].x,E[i].y,0);
                }
            }
            read(q);
            printf("Case %d:
    ",++papapa);
            for(int i=1;i<=q;i++) {
                int x,y;
                read(x),read(y);
                change_range(x,y,0);
                printf("%d
    ",query_tree(1)-1);
            }
            printf("
    ");
            read(n),read(m);
        }
        return 0;
    }
    
    
  • 相关阅读:
    彻底理解 Python 生成器
    Windows上虚拟环境的安装及使用
    github怎么绑定自己的域名
    解决ImportError: cannot import name HTTPSHandler
    服务器(Linux) 安装python3
    函数的参数(必选,默认,可变,关键字)
    python 异常处理(try...finally...和with...as 方法)
    LeetCode 33. 搜索旋转排序数组 | Python
    LeetCode 46. 全排列
    LeetCode 面试题51. 数组中的逆序对
  • 原文地址:https://www.cnblogs.com/tt66ea-blog/p/11657064.html
Copyright © 2020-2023  润新知