【BZOJ 4229】 4229: 选择 (线段树+树链剖分)

4229: 选择

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 67  Solved: 41

Description

现在,我想知道自己是否还有选择。
给定n个点m条边的无向图以及顺序发生的q个事件。
每个事件都属于下面两种之一:
1、删除某一条图上仍存在的边
2、询问是否存在两条边不相交的路径可以从点u出发到点v

Input

第一行三个整数n,m,q
接下来m行,每行两个整数u,v,表示u和v之间有一条边
接下来q行,每行一个大写字母o和2个整数u、v,依次表示按顺序发生的q个事件:
当o为’Z’时,表示删除一条u和v之间的边
当o为’P’时,表示询问是否存在两条边不相交的路径可以从点u出发到点v

Output

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

Sample Input

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

Sample Output

Yes
Yes
No
No

HINT

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


Source

 

 

【分析】

  我的做法跟BZOJ 1969大致一样【我改了改代码交的。。

  这题没说删完的图联通,所以最后还要处理一下。。

  然后每次询问x到y的关键边数量是否为0就好了。

  【详细做法见BZOJ 1969

 

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 using namespace std;
  7 #define Maxn 100010
  8 #define Maxm 100010
  9 
 10 struct node
 11 {
 12     int x,y,next;
 13     int bj,id;
 14 }t[Maxn*2],tt[Maxm*4];
 15 int first[Maxn],len;
 16 
 17 void ins(int x,int y)
 18 {
 19     // printf("%d -> %d\n",x,y);
 20     t[++len].x=x;t[len].y=y;
 21     t[len].next=first[x];first[x]=len;
 22 }
 23 
 24 struct nnode
 25 {
 26     int l,r,lc,rc,sm;
 27 }tr[Maxn*2];
 28 
 29 void upd(int x)
 30 {
 31     if(tr[x].l==tr[x].r||tr[x].sm!=0) return;
 32     int lc=tr[x].lc,rc=tr[x].rc;
 33     tr[lc].sm=tr[rc].sm=0;
 34 }
 35 
 36 int tot;
 37 int build(int l,int r)
 38 {
 39     int x=++tot;
 40     tr[x].l=l;tr[x].r=r;
 41     if(l!=r)
 42     {
 43         int mid=(l+r)>>1;
 44         tr[x].lc=build(l,mid);
 45         tr[x].rc=build(mid+1,r);
 46     }
 47     else tr[x].lc=tr[x].rc=0;
 48     tr[x].sm=r-l+1;
 49     return x;
 50 }
 51 
 52 void change(int x,int l,int r)
 53 {
 54     if(tr[x].l==l&&tr[x].r==r)
 55     {
 56         tr[x].sm=0;
 57         return;
 58     }
 59     upd(x);
 60     int mid=(tr[x].l+tr[x].r)>>1,lc=tr[x].lc,rc=tr[x].rc;
 61     if(r<=mid) change(lc,l,r);
 62     else if(l>mid) change(rc,l,r);
 63     else
 64     {
 65         change(lc,l,mid);
 66         change(rc,mid+1,r);
 67     }
 68     tr[x].sm=tr[lc].sm+tr[rc].sm;
 69 }
 70 
 71 int query(int x,int l,int r)
 72 {
 73     if(tr[x].sm==0) return 0;
 74     if(tr[x].l==l&&tr[x].r==r) return tr[x].sm;
 75     upd(x);
 76     int mid=(tr[x].l+tr[x].r)>>1,lc=tr[x].lc,rc=tr[x].rc;
 77     if(r<=mid) return query(lc,l,r);
 78     else if(l>mid) return query(rc,l,r);
 79     else return query(lc,l,mid)+query(rc,mid+1,r);
 80 }
 81 
 82 int tp[Maxn],sum[Maxn],son[Maxn],dfn[Maxn],dep[Maxn];
 83 int ff[Maxn];
 84 int cnt;
 85 void dfs(int x,int f)
 86 {
 87     son[x]=0;sum[x]=1;dep[x]=dep[f]+1;
 88     ff[x]=f;
 89     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
 90     {
 91         int y=t[i].y;
 92         dfs(y,x);
 93         sum[x]+=sum[y];
 94         if(son[x]==0||sum[son[x]]<sum[y]) son[x]=y;
 95     }
 96 }
 97 
 98 void dfs2(int x,int tpp)
 99 {
100     dfn[x]=++cnt;tp[x]=tpp;
101     if(son[x]) dfs2(son[x],tpp);
102     for(int i=first[x];i;i=t[i].next) if(t[i].y!=ff[x]&&t[i].y!=son[x])
103     {
104         int y=t[i].y;
105         dfs2(y,y);
106     }
107 }
108 
109 void fchange(int x,int y)
110 {
111     while(tp[x]!=tp[y])
112     {
113         if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
114         change(1,dfn[tp[x]],dfn[x]);
115         x=ff[tp[x]];
116     }
117     if(dep[x]<dep[y]) swap(x,y);
118     if(x!=y) change(1,dfn[y]+1,dfn[x]);
119 }
120 
121 int fquery(int x,int y)
122 {
123     int ans=0;
124     while(tp[x]!=tp[y])
125     {
126         if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
127         ans+=query(1,dfn[tp[x]],dfn[x]);
128         x=ff[tp[x]];
129     }
130     if(dep[x]<dep[y]) swap(x,y);
131     if(x!=y)
132     {
133         // if(dfn[y]+1>dfn[x]) while(1);
134         ans+=query(1,dfn[y]+1,dfn[x]);
135     }
136     return ans;
137 }
138 
139 int fa[Maxn];
140 int ffa(int x)
141 {
142     if(fa[x]!=x) fa[x]=ffa(fa[x]);
143     return fa[x];
144 }
145 
146 bool cmp(node x,node y)
147 {
148     if(x.x==y.x&&x.y==y.y) return x.bj<y.bj;
149     return (x.x==y.x)?(x.y<y.y):(x.x<y.x);
150 }
151 bool cmp2(node x,node y) {return x.id<y.id;}
152 
153 int ans[Maxn];
154 
155 char s[10];
156 
157 void solve()
158 {
159     int n,m,q;
160     scanf("%d%d%d",&n,&m,&q);
161     int ll=0;
162     for(int i=1;i<=m;i++)
163     {
164         int x,y;
165         ll++;
166         scanf("%d%d",&tt[ll].x,&tt[ll].y);
167         if(tt[ll].x>tt[ll].y) swap(tt[ll].x,tt[ll].y);
168         tt[ll].bj=1;//cha ru
169     }
170     int ct=0;
171     while(q--)
172     {
173         scanf("%s",s);
174         ll++;
175         scanf("%d%d",&tt[ll].x,&tt[ll].y);
176         if(tt[ll].x>tt[ll].y) swap(tt[ll].x,tt[ll].y);
177         if(s[0]=='Z') tt[ll].bj=-1;//shan chu
178         else tt[ll].bj=0;//xun wen
179         tt[ll].id=++ct;
180     }
181     sort(tt+1,tt+1+ll,cmp);
182     for(int i=1;i<=n;i++) fa[i]=i;
183     ct++;
184     int pp=0;
185     for(int i=1;i<=ll;i++)
186     {
187         if(tt[i].bj==0) continue;
188         if(tt[i].bj==1)
189         {
190             if(pp==0||tt[i].x!=tt[pp].x||tt[i].y!=tt[pp].y)
191             {
192                 if(ffa(tt[i].x)==ffa(tt[i].y))
193                 {
194                     tt[i].bj=-1;
195                     tt[i].id=ct;
196                 }
197                 else
198                 {
199                     ins(tt[i].x,tt[i].y);
200                     ins(tt[i].y,tt[i].x);
201                     fa[ffa(tt[i].x)]=tt[i].y;
202                 }
203             }
204         }
205         pp=i;
206     }
207     sort(tt+1,tt+1+ll,cmp2);
208     for(int i=ll;i>=1;i--) if(tt[i].bj==-1)
209     {
210         if(ffa(tt[i].x)!=ffa(tt[i].y))
211         {
212             ins(tt[i].x,tt[i].y);
213             ins(tt[i].y,tt[i].x);
214             fa[ffa(tt[i].x)]=tt[i].y;
215             tt[i].bj=1;
216         }
217     }
218     dep[0]=0;cnt=0;
219     for(int i=1;i<=n;i++) if(ffa(i)==i)
220     {
221         dfs(i,0);
222         dfs2(i,i);
223     }
224     build(1,n);
225     
226     ans[0]=0;
227     for(int i=ll;i>=1;i--)
228     {
229         if(tt[i].bj==1) continue;
230         if(tt[i].bj==-1)
231         {
232             fchange(tt[i].x,tt[i].y);
233         }
234         else
235         {
236             if(ffa(tt[i].x)!=ffa(tt[i].y)) ans[++ans[0]]=-1;
237             else ans[++ans[0]]=fquery(tt[i].x,tt[i].y);
238         }
239     }
240     for(int i=ans[0];i>=1;i--)
241     {
242         if(ans[i]==0) printf("Yes\n");
243         else printf("No\n");
244     }
245 }
246 
247 int main()
248 {
249     solve();
250     return 0;
251 }
View Code

【是不是打的有点丑

 

2017-03-27 10:33:13

 

posted @ 2017-03-27 10:33  konjak魔芋  阅读(364)  评论(0编辑  收藏  举报