zoukankan      html  css  js  c++  java
  • LOJ121 「离线可过」动态图连通性

    思路

    动态图连通性的板子,可惜我不会在线算法
    离线可以使用线段树分治,每个边按照存在的时间插入线段树的对应节点中,最后再dfs一下求出解即可,注意并查集按秩合并可以支持撤销操作

    由于大量使用STL跑的很慢的代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <stack>
    #include <set>
    #include <map>
    const int MAXN = 5101;
    const int MAXM = 500100;
    using namespace std;
    int n,timex=0,m,ans[MAXM],cnt;
    struct Udsu{
        int h[MAXN],fa[MAXN];
        stack<int> mer,height;
        int find(int x){
            if(fa[x]==x)
                return x;
            else
                return find(fa[x]);
        }
        bool query(int x,int y){
            return find(x)==find(y);
        }
        void merge(int x,int y){
            x=find(x);
            y=find(y);
            if(h[x]<=h[y]){
                mer.push(x);
                fa[x]=y;
                if(h[x]==h[y]){
                    h[y]++;
                    height.push(1);
                }
                else
                    height.push(0);
            }
            else{
                mer.push(y);
                fa[y]=x;
                height.push(0);
            }
        }
        void undo(void){
            int x=mer.top();
            mer.pop();
            int val=height.top();
            height.pop();
            h[fa[x]]-=val;
            fa[x]=x;
        }
        void init(void){
            for(int i=1;i<=n;i++)
                h[i]=1,fa[i]=i;
        }
    }DSU;
    struct edge{
        int u,v;
        bool operator < (const edge &b) const{
            return u<b.u||(u==b.u&&v<b.v);
        }
    };
    struct Node{
        int le,u,v;//-1 add else query
        bool operator < (const Node &b) const{
            return le<b.le;
        }
    };
    map<edge,int> M;
    vector<Node> seg[MAXM<<2];
    void add(int l,int r,int L,int R,int o,int le,int u,int v){
        // printf("add l=%d r=%d L=%d R=%d o=%d
    ",l,r,L,R,o);
        // Sleep(700);
        if(L<=l&&r<=R){
            seg[o].push_back((Node){le,u,v});
            return;
        }
        int mid=(l+r)>>1;
        if(L<=mid)
            add(l,mid,L,R,o<<1,le,u,v);
        if(R>mid)
            add(mid+1,r,L,R,o<<1|1,le,u,v);
    }
    void dfs(int l,int r,int o){
        // printf("l=%d r=%d o=%d
    ",l,r,o);
        sort(seg[o].begin(),seg[o].end());
        for(int i=0;i<seg[o].size();i++){
            if(seg[o][i].le==-1){
                DSU.merge(seg[o][i].u,seg[o][i].v);
                // printf("link %d %d
    ",seg[o][i].u,seg[o][i].v);
            }
            else{
                ans[seg[o][i].le]=DSU.query(seg[o][i].u,seg[o][i].v);
                // printf("query %d %d
    ",seg[o][i].u,seg[o][i].v);
            }
        }
        if(l!=r){
            int mid=(l+r)>>1;
            dfs(l,mid,o<<1);
            dfs(mid+1,r,o<<1|1);
        }
        for(int i=0;i<seg[o].size();i++)
            if(seg[o][i].le==-1){
                // printf("undo
    ");
                DSU.undo();
                }
    }
    int main(){
        scanf("%d %d",&n,&m);
        DSU.init();
        for(int i=1;i<=m;i++){
            ++timex;
            int opt,u,v;
            scanf("%d %d %d",&opt,&u,&v);
            if(u>v)
                swap(u,v);
            if(opt==0){
                M[((edge){u,v})]=timex;
            }
            if(opt==1){
                // printf("addtime=%d endtime=%d
    ",M[((edge){u,v})],timex);
                add(1,m+1,M[((edge){u,v})],timex,1,-1,u,v);
                M.erase((edge){u,v});
            }
            if(opt==2){
                add(1,m+1,timex,timex,1,++cnt,u,v);
            }
        }
        ++timex;
        for(map<edge,int>::iterator it=M.begin();it!=M.end();it++){
            add(1,m+1,(*it).second,m+1,1,-1,(*it).first.u,(*it).first.v);
        }
        dfs(1,m+1,1);
        for(int i=1;i<=cnt;i++){
            printf("%s
    ",(ans[i])?"Y":"N");
        }
        return 0;
    }
    
    
  • 相关阅读:
    react 安装脚手架过程
    微信小程序-分享功能
    echarts 实现多图联动显示tooltip
    dom 相同父节点查找
    js 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果
    vue手写el-form组件
    vue组件传值、通信
    vue项目打包桌面应用 exe程序 以及打包为安装程序exe
    vue 使用echarts来制作图表
    前端数据可视化插件-图表
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10480868.html
Copyright © 2011-2022 走看看