zoukankan      html  css  js  c++  java
  • bzoj4025: 二分图

    4025: 二分图

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 1127  Solved: 420
    [Submit][Status][Discuss]

    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

    HINT

    样例说明:

    0时刻,出现两条边1-2和2-3。

    第1时间段内,这个图是二分图,输出Yes。

    1时刻,出现一条边1-3。

    第2时间段内,这个图不是二分图,输出No。

    2时刻,1-2和1-3两条边消失。

    第3时间段内,只有一条边2-3,这个图是二分图,输出Yes。

     

    数据范围:

    n<=100000,m<=200000,T<=100000,1<=u,v<=n,0<=start<=end<=T。
     
    题解
      我们想象对时间轴建一颗线段树,然后对于每一条边有个存在区间,想象线段树区间覆盖。我们从顶走到底的一个点的话,把所有覆盖路径上节点的边都拿出来处理,这样就得到了这个时间点的状态。我们用这样的思想对时间轴进行分治,对于当前处理的某个时间段,首先把完全覆盖这个时间段[l,r]的边给处理一下,然后把开始时间<=mid的找出来递归处理[l,mid],再把结束时间>=mid+1的拿出来递归处理[mid+1,r]
      具体实现的方法是可撤销带权并查集,权是到根的路径长度的奇偶,每次处理完一个区间,就把这个区间所有的合并操作全部撤销……这个好像挺简单的网上应该都有……有点像是ahoi2013的某道题。
      1 program j01;
      2 const maxn=100086;
      3 type edge=record u,v,st,ed:longint; end;
      4 var e:array[0..2*maxn]of edge;
      5     st:array[0..2*maxn]of longint;
      6     fa,d:array[0..maxn]of longint;
      7     a:array[0..maxn]of boolean;
      8     n,m,t,i,top:longint;
      9  
     10 procedure swap(var a,b:edge);
     11 var c:edge;
     12 begin
     13   c:=a;a:=b;b:=c;
     14 end;
     15  
     16 procedure swap(var a,b:longint);
     17 var c:longint;
     18 begin
     19   c:=a;a:=b;b:=c;
     20 end;
     21  
     22 function ic(var a:longint):longint;
     23 begin
     24   inc(a);exit(a);
     25 end;
     26  
     27 function de(var a:longint):longint;
     28 begin
     29   de:=a;dec(a);
     30 end;
     31  
     32 function find(i:longint):longint;
     33 begin
     34   while fa[i]<>i do i:=fa[i];exit(i);
     35 end;
     36  
     37 function dep(i:longint):boolean;
     38 begin
     39   dep:=false;
     40   while fa[i]<>i do
     41   begin
     42     dep:=dep xor a[i];i:=fa[i];
     43   end;
     44 end;
     45  
     46 procedure union(u,v:longint;dd:boolean);
     47 begin
     48   if d[u]>d[v] then swap(u,v);
     49   if d[u]=d[v] then
     50   begin
     51     st[ic(top)]:=-v;inc(d[v]);
     52   end;
     53   st[ic(top)]:=u;fa[u]:=v;
     54   a[u]:=dd;
     55 end;
     56  
     57 procedure resume(now:longint);
     58 begin
     59   while top>now do
     60   begin
     61     if st[top]<0 then dec(d[-st[top]]) else
     62     begin
     63       fa[st[top]]:=st[top];a[st[top]]:=false;
     64     end;
     65     dec(top);
     66   end;
     67 end;
     68  
     69 procedure solve(l,r,m:longint);
     70 var mid,i,j,now,fx,fy:longint;dd:boolean;
     71 begin
     72   now:=top;mid:=(l+r)div 2;
     73   i:=1;
     74   while i<=m do
     75   begin
     76     if(e[i].st<=l)and(r<=e[i].ed)then
     77     begin
     78       fx:=find(e[i].u);fy:=find(e[i].v);
     79       dd:=not(dep(e[i].u) xor dep(e[i].v));
     80       if fx<>fy then union(fx,fy,dd) else
     81       begin
     82         if dd then
     83         begin
     84           for j:=l to r do writeln('No');
     85           resume(now);
     86           exit;
     87         end;
     88       end;
     89       swap(e[de(i)],e[de(m)]);
     90     end;
     91     inc(i);
     92   end;
     93   if l=r then
     94   begin
     95     writeln('Yes');resume(now);exit;
     96   end;
     97   i:=1;j:=m;
     98   while i<=j do
     99   begin
    100     if e[i].st>mid then swap(e[de(i)],e[de(j)]);
    101     inc(i);
    102   end;
    103   solve(l,mid,j);
    104   i:=1;j:=m;
    105   while i<=j do
    106   begin
    107     if e[i].ed<=mid then swap(e[de(i)],e[de(j)]);
    108     inc(i);
    109   end;
    110   solve(mid+1,r,j);
    111   resume(now);
    112 end;
    113  
    114 begin
    115   readln(n,m,t);
    116   for i:=1 to n do
    117   begin
    118     fa[i]:=i;a[i]:=false;d[i]:=1;
    119   end;
    120   i:=1;
    121   while i<=m do
    122   begin
    123     readln(e[i].u,e[i].v,e[i].st,e[i].ed);
    124     inc(e[i].st);
    125     if e[i].st>e[i].ed then
    126     begin
    127       dec(i);dec(m);
    128     end;
    129     inc(i);
    130   end;
    131   top:=0;
    132   solve(1,t,m);
    133 end.
    View Code
  • 相关阅读:
    PHP计算字符串长度,PHP如何计算短信的长度/字数?
    PHP 性能分析与实验——性能的宏观分析
    在PC机上,如何用Chrome浏览器模拟查看和调试手机的HTML5页面?
    MySQL replace into 使用详解 及 注意事项
    PHP计算两个时间段是否有交集(边界重叠不算)
    PHP计算一年有多少周,每周开始日期和结束日期
    【荐】PHP Session和Cookie,Session阻塞,Session垃圾回收,Redis共享Session,不推荐Memcached保存Session
    解决百度 ueditor v1.4.3 编辑器上传图片失真的bug?
    JS删除数组中某一项或几项的方法汇总
    如何使用PDO查询Mysql来避免SQL注入风险?ThinkPHP 3.1中的SQL注入漏洞分析!
  • 原文地址:https://www.cnblogs.com/oldjang/p/6503337.html
Copyright © 2011-2022 走看看