HDU 5458 Stability 树链剖分
来源:互联网 发布:mysql 联合主键优化 编辑:程序博客网 时间:2024/06/10 22:05
题意:给n个点m条边的无向图,图中可能包含自环和重边,现在有两种操作:
1.删掉一条(a,b)边
2.询问a->b上有多少条关键边,关键边意思为:删掉该边,使得a不能到达b。
所有删除操作都保证图是连通的。
把删除操作倒着加边来搞。
先随便建一颗树,边权为1,若加边(a,b),那么a到b的路径上的边权都赋值为0
询问a b则为a->b的边权和。用树链来搞。
//author: CHC//First Edit Time: 2015-09-21 23:32#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#include <queue>#include <set>#include <algorithm>#include <limits>using namespace std;typedef long long LL;const int MAXN=1e+4 * 3 + 1000;const int MAXM=1e+5 * 2 + 1000;const int INF = numeric_limits<int>::max();const LL LL_INF= numeric_limits<LL>::max();struct Edge { int to,next; Edge(){} Edge(int _to,int _next):to(_to),next(_next){} bool operator<(const Edge &x) const { if(to!=x.to)return to<x.to; return next<x.next; }}e[MAXM];int head[MAXN],tot;int path[MAXN];int Find(int x){ int tx=x; while(tx!=path[tx])tx=path[tx]; while(x!=path[x]){ int t=path[x]; path[x]=tx; x=t; } return tx; //return x==path[x]?x:path[x]=Find(path[x]);}bool Union(int x,int y){ x=Find(x),y=Find(y); if(x==y)return false; path[x]=y; return true;}multiset <Edge> S,V;multiset <Edge> ::iterator it,it1;void init(){ memset(head,-1,sizeof(head)); tot=0; S.clear();V.clear(); for(int i=1;i<MAXN;i++)path[i]=i;}void AddEdge(int u,int v){ e[tot]=Edge(v,head[u]); head[u]=tot++; e[tot]=Edge(u,head[v]); head[v]=tot++;}int dep[MAXN],son[MAXN],siz[MAXN],fa[MAXN],prew[MAXN];int tim,id[MAXN],rid[MAXN],top[MAXN];void dfs1(int u,int father,int w){ fa[u]=father;siz[u]=1;son[u]=-1; prew[u]=w; for(int i=head[u];~i;i=e[i].next){ int v=e[i].to; if(v!=father){ dep[v]=dep[u]+1; dfs1(v,u,1); siz[u]+=siz[v]; if(son[u]==-1||siz[v]>siz[son[u]])son[u]=v; } }}void dfs2(int u,int tp){ top[u]=tp; id[u]=++tim; rid[tim]=u; if(son[u]==-1)return ; dfs2(son[u],tp); for(int i=head[u];~i;i=e[i].next){ int v=e[i].to; if(v!=son[u]&&v!=fa[u])dfs2(v,v); }}#define lson L,mid,rt<<1#define rson mid+1,R,rt<<1|1struct Tree { int ans,flag;}tr[MAXN<<2];void pushup(int rt){ tr[rt].ans=tr[rt<<1].ans+tr[rt<<1|1].ans;}void pushdown(int rt){ if(tr[rt].flag){ tr[rt<<1].ans=tr[rt<<1|1].ans=0; tr[rt<<1].flag=tr[rt<<1|1].flag=1; tr[rt].flag=0; }}void build(int L,int R,int rt){ tr[rt].flag=0; if(L==R){ tr[rt].ans=prew[rid[L]]; tr[rt].flag=0; return ; } int mid=(L+R)>>1; build(lson);build(rson); pushup(rt);}void update(int L,int R,int rt,int l,int r){ if(tr[rt].ans==0)return ; if(l<=L&&R<=r){ tr[rt].ans=0; tr[rt].flag=1; return ; } pushdown(rt); int mid=(L+R)>>1; if(l<=mid)update(lson,l,r); if(r>mid)update(rson,l,r); pushup(rt);}int query(int L,int R,int rt,int l,int r){ if(tr[rt].ans==0)return 0; if(l<=L&&R<=r)return tr[rt].ans; pushdown(rt); int mid=(L+R)>>1,ans=0; if(l<=mid)ans+=query(lson,l,r); if(r>mid)ans+=query(rson,l,r); pushup(rt); return ans;}void updatex(int a,int b,int n){ while(top[a]!=top[b]){ if(dep[top[a]]<dep[top[b]])swap(a,b); update(1,n,1,id[top[a]],id[a]); a=fa[top[a]]; } if(a==b)return ; if(dep[a]>dep[b])swap(a,b); update(1,n,1,id[son[a]],id[b]);}int queryx(int a,int b,int n){ int ans=0; while(top[a]!=top[b]){ if(dep[top[a]]<dep[top[b]])swap(a,b); ans+=query(1,n,1,id[top[a]],id[a]); a=fa[top[a]]; } if(a==b)return ans; if(dep[a]>dep[b])swap(a,b); ans+=query(1,n,1,id[son[a]],id[b]); return ans;}struct Q { int type,a,b; void init(){ scanf("%d%d%d",&type,&a,&b); }}cs[MAXN*10];int ans[MAXN*10];int main(){ int T,n,m,q,cas=0; scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&m,&q); init(); for(int i=0,x,y;i<m;i++){ scanf("%d%d",&x,&y); if(x>y)swap(x,y); S.insert(Edge(x,y)); } //puts("here"); for(int i=0;i<q;i++){ cs[i].init(); if(cs[i].type==1){ if(cs[i].a>cs[i].b)swap(cs[i].a,cs[i].b); it=S.lower_bound(Edge(cs[i].a,cs[i].b)); S.erase(it); } } //puts("here"); for(it=S.begin();it!=S.end();it++){ if(Union(it->to,it->next)){ V.insert(*it); AddEdge(it->to,it->next); } } //puts("here3"); for(it=V.begin();it!=V.end();it++){ it1=S.lower_bound(*it); S.erase(it1); } //puts("here"); dep[1]=0; tim=0; dfs1(1,1,0); dfs2(1,1); build(1,n,1); for(it=S.begin();it!=S.end();it++){ updatex(it->next,it->to,n); } for(int i=q-1;i>=0;i--){ if(cs[i].type==1){ updatex(cs[i].a,cs[i].b,n); } else { ans[i]=queryx(cs[i].a,cs[i].b,n); } } printf("Case #%d:\n",++cas); for(int i=0;i<q;i++) if(cs[i].type==2)printf("%d\n",ans[i]); } return 0;}
0 0
- HDU 5458 Stability【树链剖分】
- HDU 5458 Stability 树链剖分
- HDU 5458 Stability 树链剖分
- hdu 5458 Stability
- HDU 5458 Stability
- HDU 5458 Stability(树链剖分 + 并查集)
- hdu 5458 Stability(树链剖分+强连通缩点+线段树)
- hdoj 5458 Stability 【并查集 + 树链剖分】
- HDU 5458(Stability-LCT维护连通图2点间割边个数)
- 【HDU】5458 Stability(2015 ACM/ICPC Shenyang Online)
- HDU 5458 Stability (2015 ACM/ICPC Asia Regional Shenyang Online)
- HDU 5458 Stability(树链剖分缩点并查集)
- HDOJ 5458 Stability
- Stability
- HDU 5458 Stability(LCA倍增算法, 并查集缩点(一般都是连通缩点))
- 2015 ACM/ICPC Asia Regional Shenyang OnlineHDU-5458 Stability
- Sorting Stability
- Android Stability [转]
- iOS中触摸事件详解和使用
- Mysql常用函数
- itk的编译问题
- 谈谈对账
- memcached(二)--原理
- HDU 5458 Stability 树链剖分
- 关于WPF转换.net平台的工作
- hdu1695GCD(莫比乌斯反演初步)
- 从hostmonster把域名迁到阿里云
- 如何出掉grub.cfg中的启动项
- HttpClientGetActivity
- Datastax文档Apache Cassandra v2.1 第二部分 理解Cassandra架构_节点间通信(Gossip)
- get st_dev and st_rdev
- PL/SQL(oracle) 中实现两个数据库之间表的对比,提高建表效率