zoukankan      html  css  js  c++  java
  • HDU 5333 Undirected Graph(动态树)

    题意

    给定一棵 (n) 个节点, (m) 条边的无向图,每个点有点权,有 (q) 个询问,每次询问若删去存在一个节点权值在 ([L,R]) 范围外的边,剩下的图构成了多少个连通块(询问间相互独立)。

    (1leq n,q leq 10^5)

    (1leq m leq 2 imes 10^5)

    思路

    题目意思在简化一下,就是求连接两个点权在 ([L,R]) 中的边和原图中的所有节点构成的连通块数。

    对于两维的询问,在没有强制在线的情况下,可以考虑离线消维。我们把询问按右端点升序排列,将边按照连接两点点权最大值排列,一条一条的往图中添加,加到值为 (p) 的边时,我们需回答 (R) 小于等于 (p) 的询问。

    这样加的边满足了 (R) 的要求,接下来仅需考虑 (L) ,我们令边权为连接两点权值的最小值,显然如果增加了一条权较大的边并形成了环,那么环中较小的边便没有意义了(因为权较大的边可以影响更多的询问)。那么只需要用 ( ext{LCT}) 维护一个最大生成树(下有讲解)即可。

    继续分析,如果我们加入了一条权为 (p) 的边,不难发现 (L) 值在 ([1,p]) 范围内的答案都会减少 (1)(连通块个数少 (1) );反过来,如果断开了一条权为 (p) 的边,(L) 值在 ([1,p]) 的答案都会增加 (1) 。那在维护最大生成树的过程中,实时记录每个 (L) 的答案即可,我选择用树状数组进行区间修改,单点查询。

    ( ext{LCT}) 用来维护边权,最好写的写法就是直接把边当作一个点塞进 ( ext{LCT}) 里,这个点的点权就是边权。在此基础上,用 ( ext{LCT}) 维护最小/大生成树,只需要在连接边 ((u,v)) 时询问目前的路径 ((u,v)) 的最大/小值,以及对应的边的位置,如果可以替换,就断开那条边,并连接 ((u,v))

    代码

    #include<bits/stdc++.h>
    #define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
    #define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
    template<typename T,typename _T>inline bool chk_min(T &x,const _T y){return y<x?x=y,1:0;}
    template<typename T,typename _T>inline bool chk_max(T &x,const _T y){return x<y?x=y,1:0;}
    typedef long long ll;
    const int N=1e5+5,M=2e5+5;
    template<const int maxn,const int maxm,typename T>struct Linked_list
    {
    	int head[maxn],nxt[maxm],tot;T to[maxm];
    	Linked_list(){clear();}
    	T &operator [](const int x){return to[x];}
    	void clear(){memset(head,-1,sizeof(head)),tot=0;}
    	void add(int u,T v){to[tot]=v,nxt[tot]=head[u],head[u]=tot++;}
    	#define EOR(i,G,u) for(int i=G.head[u];~i;i=G.nxt[i])
    };
    struct FenwickTree
    {
    	#define lowbit(x) ((x)&-(x))
    	int c[N],n;
    	void init(int _n){n=_n;FOR(i,0,n)c[i]=0;}
    	void update(int k,int val){for(;k<=n;k+=lowbit(k))c[k]+=val;}
    	int query(int k){int res=0;for(;k>0;k^=lowbit(k))res+=c[k];return res;}
    	void update(int l,int r,int val){update(l,val),update(r+1,-val);}
    	#undef lowbit
    };
    struct Query
    {
    	int id,l,r;
    	bool operator <(const Query &_)const{return r<_.r;}
    };
    struct node
    {
    	int x,y;
    	node(int _x=0,int _y=0){x=_x,y=_y;}
    	bool operator <(const node &_)const{return y<_.y;}
    };
    struct LinkCutTree
    {
    	int ch[N+M][2],fa[N+M];node pw[N+M],Mi[N+M];
    	int stk[N+M],tp;
    	bool rev[N+M];
    	void init(){create(0,node(1e9,1e9));}
    	void create(int x,node val){ch[x][0]=ch[x][1]=fa[x]=rev[x]=0;pw[x]=Mi[x]=val;}
    	bool isroot(int x){return x!=ch[fa[x]][0]&&x!=ch[fa[x]][1];}
    	void reved(int x)
    	{
    		std::swap(ch[x][0],ch[x][1]);
    		rev[x]^=1;
    	}
    	void push_up(int x)
    	{
    		Mi[x]=std::min(std::min(Mi[ch[x][0]],Mi[ch[x][1]]),pw[x]);
    	}
    	void push_down(int x)
    	{
    		if(rev[x])
    		{
    			if(ch[x][0])reved(ch[x][0]);
    			if(ch[x][1])reved(ch[x][1]);
    			rev[x]=0;
    		}
    	}
    	void rotate(int x)
    	{
    		int y=fa[x],z=fa[y],k=(x==ch[y][1]);
    		if(!isroot(y))ch[z][y==ch[z][1]]=x; fa[x]=z;
    		ch[y][k]=ch[x][!k]; if(ch[x][!k])fa[ch[x][!k]]=y;
    		ch[x][!k]=y,fa[y]=x;
    		push_up(y),push_up(x);
    	}
    	void splay(int x)
    	{
    		stk[tp=1]=x;
    		for(int y=x;!isroot(y);y=fa[y])stk[++tp]=fa[y];
    		while(tp)push_down(stk[tp]),tp--;
    		while(!isroot(x))
    		{
    			int y=fa[x],z=fa[y];
    			if(!isroot(y))(x==ch[y][1])==(y==ch[z][1])?rotate(y):rotate(x);
    			rotate(x);
    		}
    	}
    	void access(int x)
    	{
    		for(int y=0;x;y=x,x=fa[x])
    			splay(x),ch[x][1]=y,push_up(x);
    	}
    	void make_root(int x)
    	{
    		access(x),splay(x),reved(x);
    	}
    	int get_root(int x)
    	{
    		access(x),splay(x);
    		while(ch[x][0])push_down(x),x=ch[x][0];
    		splay(x);
    		return x;
    	}
    	bool link(int x,int y)
    	{
    		make_root(x);
    		if(get_root(y)==x)return false;
    		fa[x]=y;
    		return true;
    	}
    	bool cut(int x,int y)
    	{
    		make_root(x);
    		if(get_root(y)!=x||ch[x][1]!=y||ch[y][0])return false;
    		ch[x][1]=fa[y]=0;
    		push_up(x);
    		return true;
    	}
    	bool lift(int x,int y)
    	{
    		make_root(x);
    		return get_root(y)==x;
    	}
    	node query(int x,int y)
    	{
    		lift(x,y);
    		return Mi[x];
    	}
    };
    Linked_list<N,M,int>G;
    LinkCutTree LCT;
    FenwickTree FT;
    Query qry[N];int otp[N];
    int U[N+M],V[N+M],cur;
    int n,m,q;
    
    int main()
    {
    	LCT.init();
    	while(~scanf("%d%d%d",&n,&m,&q))
    	{
    		G.clear();FT.init(n);cur=n;
    		FT.update(1,n,n);
    		FOR(i,1,n)LCT.create(i,node(1e9,1e9));
    		FOR(i,1,m)
    		{
    			int u,v;
    			scanf("%d%d",&u,&v);
    			if(u>v)std::swap(u,v);
    			G.add(v,u);
    		}
    		FOR(i,1,q)scanf("%d%d",&qry[i].l,&qry[i].r),qry[i].id=i;
    		std::sort(qry+1,qry+q+1);
    		int j=1;
    		FOR(i,1,n)
    		{
    			EOR(k,G,i)
    			{
    				int l=G[k];bool flg=0;
    				if(!LCT.lift(i,l))flg=1;
    				else
    				{
    					node tmp=LCT.query(i,l);
    					if(tmp.y<l)
    					{
    						LCT.cut(tmp.x,U[tmp.x]),LCT.cut(tmp.x,V[tmp.x]);
    						FT.update(1,tmp.y,1);
    						flg=1;
    					}
    				}
    				if(flg)
    				{
    					cur++;
    					LCT.create(cur,node(cur,l));
    					U[cur]=i,V[cur]=l;
    					LCT.link(cur,i),LCT.link(cur,l);
    					FT.update(1,l,-1);
    				}
    			}
    			while(j<=q&&qry[j].r<=i)
    			{
    				otp[qry[j].id]=FT.query(qry[j].l);
    				j++;
    			}
    		}
    		FOR(i,1,q)printf("%d
    ",otp[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Multi-Agent Actor-Critic for Mixed Cooperative-Competitive Environments环境代码详解
    zc.buildout构建项目时报错‘AttributeError: '_NamespacePath' object has no attribute 'sort'’
    利用Jenkins打包ISO和QCOW2镜像文件
    解决python pip安装提示"not a supported wheel on this platform"
    Kali 2017.3开启VNC远程桌面登录
    Jenkins邮件扩展插件Email Extension Plugin配置使用
    Jenkins执行sudo权限的设置
    如何解决源码安装软件中make时一直重复打印configure信息
    CentOS 7下安装配置proftpd搭建ftp服务器
    如何使用capedit分割数据包文件
  • 原文地址:https://www.cnblogs.com/Paulliant/p/10556738.html
Copyright © 2011-2022 走看看