BZOJ4025: 二分图(LCT)

Description

神犇有一个n个节点的图。因为神犇是神犇,所以在T时间内一些边会出现后消失。神犇要求出每一时间段内这个图是否是二分图。这么简单的问题神犇当然会做了,于是他想考考你。

Input

输入数据的第一行是三个整数n,m,T。
第2行到第m+1行,每行4个整数u,v,start,end。第i+1行的四个整数表示第i条边连接u,v两个点,这条边在start时刻出现,在第end时刻消失。

Output

输出包含T行。在第i行中,如果第i时间段内这个图是二分图,那么输出“Yes”,否则输出“No”,不含引号。

Sample Input

3 3 3
1 2 0 2
2 3 0 3
1 3 1 2

Sample Output

Yes
No
Yes

解题思路:

LCT维护图的连通性很好的一道题。

发现如果是树那么一定可以,如果奇数环一定不是。

离线一下,然后维护一颗树中最早被删除的点。

维护最后一条边(可以用数组存)

最后判一下就好了。

代码:

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define lll tr[spc].ch[0]
  5 #define rrr tr[spc].ch[1]
  6 #define ls ch[0]
  7 #define rs ch[1]
  8 using std::swap;
  9 using std::sort;
 10 const int E=100005;
 11 struct trnt{
 12     int ch[2];
 13     int fa;
 14     int lzt;
 15     int val;
 16     int mnp;
 17     int mn;
 18     int sum;
 19     int tip;
 20     bool anc;
 21 }tr[1000000];
 22 struct ent{
 23     int f,t,dl;
 24 }e[1000000];
 25 struct Event{
 26     bool cmd;
 27     int f,t,tpc;
 28     int no;
 29 }ev[1000000];
 30 int n,m,T;
 31 int num;
 32 int cnt;
 33 bool onr[1000000];
 34 bool odd[1000000];
 35 bool whc(int spc)
 36 {
 37     return tr[tr[spc].fa].rs==spc;
 38 }
 39 void pushup(int spc)
 40 {
 41     tr[spc].sum=tr[spc].val;
 42     tr[spc].mn=tr[spc].tip;
 43     tr[spc].mnp=spc;
 44     if(lll)
 45     {
 46         tr[spc].sum+=tr[lll].sum;
 47         if(tr[spc].mn>tr[lll].mn)
 48         {
 49             tr[spc].mn=tr[lll].mn;
 50             tr[spc].mnp=tr[lll].mnp;
 51         }
 52     }
 53     if(rrr)
 54     {
 55         tr[spc].sum+=tr[rrr].sum;
 56         if(tr[spc].mn>tr[rrr].mn)
 57         {
 58             tr[spc].mn=tr[rrr].mn;
 59             tr[spc].mnp=tr[rrr].mnp;
 60         }
 61     }
 62     return ;
 63 }
 64 void trr(int spc)
 65 {
 66     if(!spc)
 67         return ;
 68     tr[spc].lzt^=1;
 69     swap(lll,rrr);
 70     return ;
 71 }
 72 void pushdown(int spc)
 73 {
 74     if(tr[spc].lzt)
 75     {
 76         tr[spc].lzt=0;
 77         trr(lll);
 78         trr(rrr);
 79     }
 80     return ;
 81 }
 82 void recal(int spc)
 83 {
 84     if(!tr[spc].anc)
 85         recal(tr[spc].fa);
 86     pushdown(spc);
 87     return ;
 88 }
 89 void rotate(int spc)
 90 {
 91     int f=tr[spc].fa;
 92     bool k=whc(spc);
 93     tr[f].ch[k]=tr[spc].ch[!k];
 94     tr[spc].ch[!k]=f;
 95     if(tr[f].anc)
 96     {
 97         tr[spc].anc=1;
 98         tr[f].anc=0;
 99     }else
100         tr[tr[f].fa].ch[whc(f)]=spc;
101     tr[spc].fa=tr[f].fa;
102     tr[f].fa=spc;
103     tr[tr[f].ch[k]].fa=f;
104     pushup(f);
105     pushup(spc);
106     return ;
107 }
108 void splay(int spc)
109 {
110     recal(spc);
111     while(!tr[spc].anc)
112     {
113         int f=tr[spc].fa;
114         if(tr[f].anc)
115         {
116             rotate(spc);
117             return ;
118         }
119         if(whc(spc)^whc(f))
120             rotate(spc);
121         else
122             rotate(f);
123         rotate(spc);
124     }
125     return ;
126 }
127 void access(int spc)
128 {
129     int lst=0;
130     while(spc)
131     {
132         splay(spc);
133         tr[rrr].anc=1;
134         tr[lst].anc=0;
135         rrr=lst;
136         pushup(spc);
137         lst=spc;
138         spc=tr[spc].fa;
139     }
140     return ;
141 }
142 void Mtr(int spc)
143 {
144     access(spc);
145     splay(spc);
146     trr(spc);
147     return ;
148 }
149 void split(int x,int y)
150 {
151     Mtr(x);
152     access(y);
153     splay(y);
154     return ;
155 }
156 int finf(int spc)
157 {
158     access(spc);
159     splay(spc);
160     while(lll)
161         spc=lll;
162     return spc;
163 }
164 void link(int x,int y)
165 {
166     Mtr(x);
167     tr[x].fa=y;
168     return ;
169 }
170 void cut(int x,int y)
171 {
172     split(x,y);
173     tr[x].fa=tr[y].ls=0;
174     tr[x].anc=1;
175     pushup(y);
176     return ;
177 }
178 void Insert(int frm,int twd,int spc,int Time)
179 {
180     if(frm==twd)
181     {
182         num++;
183         odd[spc]=true;
184         return ;
185     }
186     Mtr(frm);
187     if(finf(twd)==frm)
188     {
189         int x=tr[twd].mnp-E;
190         if(e[x].dl<Time)
191         {
192             onr[x]=false;
193             onr[spc]=true;
194             if(tr[twd].sum%2==0)
195             {
196                 odd[x]=true;
197                 num++;
198             }
199             cut(e[x].f,x+E);
200             cut(e[x].t,x+E);
201             link(frm,spc+E);
202             link(twd,spc+E);
203         }else{
204             if(tr[twd].sum%2==0)
205             {
206                 odd[spc]=true;
207                 num++;
208             }
209         }
210     }else{
211         link(frm,spc+E);
212         link(twd,spc+E);
213         onr[spc]=true;
214     }
215     return ;
216 }
217 void Delete(int frm,int twd,int spc)
218 {
219     if(onr[spc])
220     {
221         cut(frm,spc+E);
222         cut(twd,spc+E);
223         onr[spc]=false;
224         return ;
225     }
226     if(odd[spc])
227     {
228         odd[spc]=false;
229         num--;
230     }
231     return ;
232 }
233 bool cmp(Event x,Event y)
234 {
235     return x.tpc<y.tpc;
236 }
237 int main()
238 {
239     scanf("%d%d%d",&n,&m,&T);
240     for(int i=1;i<=n;i++)
241     {
242         tr[i].anc=1;
243         tr[i].tip=0x3f3f3f3f;
244     }
245     for(int i=1;i<=m;i++)
246     {
247         int a,b,c,d;
248         scanf("%d%d%d%d",&a,&b,&c,&d);
249         ev[++cnt]=(Event){0,a,b,c,i};
250         ev[++cnt]=(Event){1,a,b,d,i};
251         e[i]=(ent){a,b,d};
252         int spc=i+E;
253         tr[spc].anc=1;
254         tr[spc].mn=d;
255         tr[spc].tip=d;
256         tr[spc].mnp=i;
257         tr[spc].val=1;
258     }
259     sort(ev+1,ev+cnt+1,cmp);
260     for(int i=1,hpn=1;i<=T;i++)
261     {
262         for(;(hpn<=cnt)&&(ev[hpn].tpc<i);hpn++)
263         {
264             Event x=ev[hpn];
265             if(!x.cmd)
266                 Insert(x.f,x.t,x.no,e[x.no].dl);
267             else
268                 Delete(x.f,x.t,x.no);
269         }
270         if(num)
271             puts("No");
272         else
273             puts("Yes");
274     }
275     return 0;
276 }

 

posted @ 2018-12-13 21:18  Unstoppable728  阅读(227)  评论(0编辑  收藏  举报