zoukankan      html  css  js  c++  java
  • bzoj 4025 二分图 lct

    题目传送门

    题解:

    首先关于二分图的性质, 就是没有奇环边。 题目其实就是让你判断每个时段之内有没有奇环。

    其次 lct 只能维护树,(反正对于我这种菜鸟选手只会维护树), 那么对于一棵树来说, 填上一条边会形成奇数环,或者偶数环。

    现在我们考虑偶数环, 对于偶数环来说, 如果加上一条边都能使得这个图出现一个奇数环, 我们现在任意删除一条边,都还是会存在一个奇数环。

    那么当出现偶数环的情况下, 我们可以删除一条边, 保存树的性质。

    当出现奇数环的时候, 我们也需要删除某一条边, 并且需要标记被树上删除的那个边是什么边,直到那个边消失之前, 这个图就存在奇数环。

    我们现在按照边的消失的时间从小到大删除边。 因为找替换边太麻烦了, 不好处理。 我们按照消失的时间处理之后, 就一定不会存在替换的边。

    删除的时候, 也要顺带删除掉标记。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("2.in","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define lch(x) tr[x].son[0]
     12 #define rch(x) tr[x].son[1]
     13 #define max3(a,b,c) max(a,max(b,c))
     14 #define min3(a,b,c) min(a,min(b,c))
     15 typedef pair<int,int> pll;
     16 const int inf = 0x3f3f3f3f;
     17 const LL INF = 0x3f3f3f3f3f3f3f3f;
     18 const LL mod =  (int)1e9+7;
     19 const int N = 5e5 + 100;
     20 struct Node{
     21     int rev, rt, sz;
     22     int son[2], pre;
     23     int t, tt,  id;
     24     void init(){
     25         sz = rt = 1; rev = pre = son[0] = son[1] = 0;
     26         tt = t = inf;
     27     }
     28 }tr[N];
     29 void Push_Rev(int x){
     30     if(!x) return ;
     31     swap(lch(x), rch(x));
     32     tr[x].rev ^= 1;
     33 }
     34 void Push_Up(int x){
     35     if(!x) return ;
     36     tr[x].sz = tr[lch(x)].sz + tr[rch(x)].sz + 1;
     37     tr[x].id = x;
     38     tr[x].tt = tr[x].t;
     39     if(tr[x].tt > tr[lch(x)].tt) tr[x].id = tr[lch(x)].id, tr[x].tt = tr[lch(x)].tt;
     40     if(tr[x].tt > tr[rch(x)].tt) tr[x].id = tr[rch(x)].id, tr[x].tt = tr[rch(x)].tt;
     41 }
     42 void Push_Down(int x){
     43    if(tr[x].rev){
     44         tr[x].rev = 0;
     45         Push_Rev(lch(x));
     46         Push_Rev(rch(x));
     47     }
     48 }
     49 void Rev(int x){
     50     if(!tr[x].rt) Rev(tr[x].pre);
     51     Push_Down(x);
     52 }
     53 void rotate(int x){
     54     if(tr[x].rt) return;
     55     int y = tr[x].pre, z = tr[y].pre;
     56     int k = (rch(y) == x);
     57     tr[y].son[k] = tr[x].son[k^1];
     58     tr[tr[y].son[k]].pre = y;
     59     tr[x].son[k^1] = y;
     60     tr[y].pre = x;
     61     tr[x].pre = z;
     62     if(tr[y].rt) tr[y].rt = 0, tr[x].rt = 1;
     63     else tr[z].son[rch(z) == y] = x;
     64     Push_Up(y);
     65 }
     66 void Splay(int x){
     67      Rev(x);
     68      while(!tr[x].rt){
     69         int y = tr[x].pre, z = tr[y].pre;
     70         if(!tr[y].rt){
     71             if(( x == rch(y) ) != (y == rch(z))) rotate(y);
     72             else rotate(x);
     73         }
     74         rotate(x);
     75     }
     76     Push_Up(x);
     77 }
     78 void Access(int x){
     79     int y = 0;
     80     do{
     81         Splay(x);
     82         tr[rch(x)].rt = 1;
     83         rch(x) = y;
     84         tr[y].rt = 0;
     85         Push_Up(x);
     86         y = x;
     87         x = tr[x].pre;
     88     }while(x);
     89 }
     90 void Make_rt(int x){
     91     Access(x);
     92     Splay(x);
     93     Push_Rev(x);
     94 }
     95 void link(int u, int v){
     96     Make_rt(u);
     97     tr[u].pre = v;
     98 }
     99 void cut(int u, int v){
    100     Make_rt(u);
    101     Access(v);
    102     Splay(v);
    103     tr[lch(v)].pre = 0;
    104     tr[lch(v)].rt = 1;
    105     tr[v].pre = 0;
    106     lch(v) = 0;
    107 }
    108 bool judge(int u, int v){
    109     while(tr[u].pre) u = tr[u].pre;
    110     while(tr[v].pre) v = tr[v].pre;
    111     return u == v;
    112 }
    113 int n, m, u, v, st, ed, T, id, odd, t;
    114 int tot;
    115 int vis[N], in[N];
    116 struct node{
    117     int u, v, id, t, t2;
    118     bool operator < (const node & x) const {
    119         if(t != x.t) return t < x.t;
    120         return t2 < x.t2;
    121     }
    122 }A[N];
    123 void add(int u, int v, int id, int t, int t2){
    124     ++tot;
    125     A[tot].u = u; A[tot].v = v; A[tot].id = id;
    126     A[tot].t = t; A[tot].t2 = t2;
    127 }
    128 int main(){
    129     tr[0].tt = tr[0].t = inf;
    130     scanf("%d%d%d", &n, &m, &T);
    131     for(int i = 1; i <= n+m; i++)
    132         tr[i].init();
    133     for(int i = 1; i <= m; i++){
    134         scanf("%d%d%d%d", &u, &v, &st, &ed);
    135         tr[i+n].t = ed;
    136         if(st == ed) continue;
    137         add(u, v, n+i, st, ed);
    138         add(u, v, n+i, ed, -1);
    139     }
    140     sort(A+1, A+1+tot);
    141     int j = 1;
    142     for(int i = 0; i < T; i++){
    143         while(j <= tot && A[j].t == i){
    144             u = A[j].u, v = A[j].v, id = A[j].id, t = A[j].t2;
    145             if(t == -1){
    146                 if(in[id]){
    147                     cut(u, id);
    148                     cut(v, id);
    149                 }
    150                 odd -= vis[id];
    151             }
    152             else {
    153                 if(u == v) {
    154                     vis[id] = 1;
    155                     odd++;
    156                 }
    157                 else {
    158                     if(!judge(u, v)){
    159                         link(u, id);
    160                         link(v, id);
    161                         in[id] = 1;
    162 
    163                     }
    164                     else {
    165                         Make_rt(u);
    166                         Access(v);
    167                         Splay(v);
    168                         int sz = tr[v].sz / 2;
    169                         int p = tr[v].id;
    170                         int tt = tr[v].tt;
    171                         if(tt >= t){
    172                             if(sz%2 == 0){
    173                                 odd++;
    174                                 vis[id] = 1;
    175                             }
    176                         }
    177                         else {
    178                             if(sz%2 == 0){
    179                                 odd++;
    180                                 vis[p] = 1;
    181                             }
    182                             cut(u, p);
    183                             cut(v, p);
    184                             in[p] = 0;
    185                             link(u, id);
    186                             link(v, id);
    187                             in[id] = 1;
    188                         }
    189                     }
    190                 }
    191 
    192             }
    193             j++;
    194         }
    195         if(odd) puts("No");
    196         else puts("Yes");
    197     }
    198     return 0;
    199 }
    View Code
  • 相关阅读:
    jmeter的beanshell脚本编写
    基于 Flask 的简易 Mock 平台
    mock-server
    linux环境jmeter- java环境安装配置
    服务器监控环境搭建 telegraf+influxdb+grafana框架
    聚类算法:凝聚层次聚类
    python中cursor操作数据库
    python中if __name__ == '__main__': 的解析
    python连接mysql数据库
    Python3.5,flask在命令行执行 [python] view plain copy import pymysql 连接mysql数据库MySQLdb
  • 原文地址:https://www.cnblogs.com/MingSD/p/9509976.html
Copyright © 2011-2022 走看看