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
1 2 0 2
2 3 0 3
1 3 1 2
Sample Output
Yes
No
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 }