博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
选择 (动态树)
阅读量:5875 次
发布时间:2019-06-19

本文共 3931 字,大约阅读时间需要 13 分钟。

题目描述:

现在,我想知道自己是否还有选择。

给定n个点m条边的无向图以及顺序发生的q个事件。

每个事件都属于下面两种之一:

1、删除某一条图上仍存在的边

2、询问是否存在两条边不相交的路径可以从点u出发到点v

输入:

第一行三个整数n,m,q

接下来m行,每行两个整数u,v,表示u和v之间有一条边

接下来q行,每行一个大写字母o和2个整数u、v,依次表示按顺序发生的q个事件:

当o为’Z’时,表示删除一条u和v之间的边

当o为’P’时,表示询问是否存在两条边不相交的路径可以从点u出发到点v

输出:

对于每组询问,如果存在,输出Yes,否则输出No

样例输入:

7 8 7

1 2

1 3

1 4

2 3

3 4

3 7

7 4

5 6

Z 1 4

P 1 3

P 2 4

Z 1 3

P 1 3

Z 6 5

P 5 6

 

样例输出:

Yes

Yes

No

No

 

数据规模和约定:

对于20%的数据,max(n,m,q)<=100

对于全部数据,max(n,m,q)<=100000

思路:离线做,用动态树维护连通性,对于已经在同一个连通分块里面的两个点,将这两个点之间的所有点全部缩成一个点,这个点就是最上边的那个,也就是split(x,y)以后的y,然后询问的时候,倒着做,拆边变成加边,对于两个询问点,询问他们是不是在同一个缩的点内,如果是,那么他们就有两条边不相交的路线。

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 struct edge{ 8 int u,v,id; 9 }e[200005],ask[200005]; 10 std::map
>mp; 11 int n,m,q,ts[500005],tx[500005]; 12 int ch[200005][2],fa[200005],f[200005],st[200005],rev[200005],ans[200005]; 13 int read(){ 14 char ch=getchar();int t=0,ff=1; 15 while (ch<'0'||ch>'9'){ if (ch=='-') ff=-1;ch=getchar();} 16 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 17 return t*ff; 18 } 19 int Find(int x){ 20 int top=0,i; 21 if (x==f[x]) return x; 22 for (i=x;f[i]!=i;i=f[i]){ 23 ts[++top]=i; 24 } 25 int key=i; 26 for (int i=top;i>=1;i--) 27 f[ts[i]]=key; 28 return key; 29 } 30 bool isroot(int x){ 31 fa[x]=Find(fa[x]); 32 return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; 33 } 34 void updata(int x){} 35 void pushdown(int x){ 36 int l=ch[x][0],r=ch[x][1]; 37 if (rev[x]){ 38 rev[x]^=1; 39 rev[l]^=1;rev[r]^=1; 40 std::swap(ch[x][0],ch[x][1]); 41 } 42 } 43 void rotate(int x){ 44 int y=fa[x],z=fa[y],l,r; 45 if (ch[y][0]==x) l=0;else l=1;r=l^1; 46 if (!isroot(y)){ 47 if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x; 48 } 49 fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; 50 ch[y][l]=ch[x][r];ch[x][r]=y; 51 updata(y);updata(x); 52 } 53 void splay(int x){ 54 int top=0;st[++top]=x; 55 for (int i=x;!isroot(i);i=fa[i]){ 56 st[++top]=fa[i]; 57 } 58 for (int i=top;i>=1;i--) pushdown(st[i]); 59 while (!isroot(x)){ 60 int y=fa[x],z=fa[y]; 61 if (!isroot(y)){ 62 if (ch[y][0]==x^ch[z][0]==y) rotate(x); 63 else rotate(y); 64 } 65 rotate(x); 66 } 67 } 68 void access(int x){ 69 for (int t=0;x;t=x,fa[x]=Find(fa[x]),x=fa[x]){ 70 splay(x); 71 ch[x][1]=t; 72 updata(x); 73 } 74 } 75 int find(int x){ 76 access(x);splay(x); 77 while (ch[x][0]) x=ch[x][0]; 78 return x; 79 } 80 void makeroot(int x){ 81 access(x);splay(x);rev[x]^=1; 82 } 83 void split(int x,int y){ 84 makeroot(x);access(y);splay(y); 85 } 86 void bfs(int x){ 87 int h=1,t=1;tx[h]=x; 88 for (;h<=t;h++){ 89 if (ch[tx[h]][0]) tx[++t]=ch[tx[h]][0]; 90 if (ch[tx[h]][1]) tx[++t]=ch[tx[h]][1]; 91 } 92 for (int i=1;i<=t;i++){ 93 if (i!=1) fa[tx[i]]=0; 94 f[tx[i]]=x;ch[tx[i]][0]=ch[tx[i]][1]=0; 95 } 96 } 97 void link(int x,int y){ 98 x=Find(x);y=Find(y); 99 if (find(x)!=find(y)){100 makeroot(x);101 fa[x]=y;102 }else{103 split(x,y);104 bfs(y);105 }106 }107 int main(){108 n=read();m=read();q=read();109 for (int i=1;i<=n;i++) f[i]=i;110 for (int i=1;i<=m;i++){111 e[i].u=read();e[i].v=read();112 if (e[i].u>e[i].v) std::swap(e[i].u,e[i].v);113 mp[e[i].u][e[i].v]++;114 }115 char opt[2];116 for (int i=1;i<=q;i++){117 scanf("%s",opt+1);118 if (opt[1]=='Z') ask[i].id=1;119 else ask[i].id=2;120 ask[i].u=read();ask[i].v=read();121 if (ask[i].u>ask[i].v) std::swap(ask[i].u,ask[i].v);122 if (ask[i].id==2) continue;123 if (mp[ask[i].u][ask[i].v]>0) mp[ask[i].u][ask[i].v]--;124 else ask[i].id=0;125 }126 for (int i=1;i<=m;i++)127 if (mp[e[i].u][e[i].v]>0){128 link(e[i].u,e[i].v);129 }130 for (int i=q;i>=1;i--)131 if (ask[i].id==1){132 link(ask[i].u,ask[i].v);133 }else134 if (ask[i].id==2)135 {136 if (Find(ask[i].u)!=Find(ask[i].v)) ans[i]=2;137 else ans[i]=1;138 }139 for (int i=1;i<=q;i++)140 if (ask[i].id==2){141 if (ans[i]==1) puts("Yes");142 else puts("No");143 }144 }

 

转载于:https://www.cnblogs.com/qzqzgfy/p/5537878.html

你可能感兴趣的文章
远程协助
查看>>
Scrum实施日记 - 一切从零开始
查看>>
关于存储过程实例
查看>>
配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler” 解决办法...
查看>>
AIX 7.1 install python
查看>>
PHP盛宴——经常使用函数集锦
查看>>
重写 Ext.form.field 扩展功能
查看>>
Linux下的搜索查找命令的详解(locate)
查看>>
福利丨所有AI安全的讲座里,这可能是最实用的一场
查看>>
开发完第一版前端性能监控系统后的总结(无代码)
查看>>
Python多版本情况下四种快速进入交互式命令行的操作技巧
查看>>
MySQL查询优化
查看>>
【Redis源码分析】如何在Redis中查找大key
查看>>
关于链接文件的探讨
查看>>
android app启动过程(转)
查看>>
Linux—源码包安装
查看>>
JDK8中ArrayList的工作原理剖析
查看>>
安装gulp及相关插件
查看>>
如何在Linux用chmod来修改所有子目录中的文件属性?
查看>>
Applet
查看>>