zoukankan      html  css  js  c++  java
  • HDU 5458 Stability

    Stability

    Time Limit: 2000ms
    Memory Limit: 102400KB
    This problem will be judged on HDU. Original ID: 5458
    64-bit integer IO format: %I64d      Java class name: Main
     

    Given an undirected connected graph G with n nodes and m edges, with possibly repeated edges and/or loops. The stability of connectedness between node u and node v is defined by the number of edges in this graph which determines the connectedness between them (once we delete this edge, node u and v would be disconnected).

    You need to maintain the graph G, support the deletions of edges (though we guarantee the graph would always be connected), and answer the query of stability for two given nodes.


    Input
    There are multiple test cases(no more than 3 cases), and the first line contains an integer t, meaning the totally number of test cases.

    For each test case, the first line contains three integers n, m and q, where 1≤n≤3×104,1≤m≤105 and 1≤q≤105. The nodes in graph G are labelled from 1 to n.

    Each of the following m lines contains two integers u and v describing an undirected edge between node u and node v.

    Following q lines - each line describes an operation or a query in the formats:
    ⋅ 1 a b: delete one edge between a and b. We guarantee the existence of such edge.
    ⋅ 2 a b: query the stability between a and b.


    Output
    For each test case, you should print first the identifier of the test case.

    Then for each query, print one line containing the stability between corresponding pair of nodes.


    Sample Input
    1
    10 12 14
    1 2
    1 3
    2 4
    2 5
    3 6
    4 7
    4 8
    5 8
    6 10
    7 9
    8 9
    8 10
    2 7 9
    2 7 10
    2 10 6
    2 10 5
    1 10 6
    2 10 1
    2 10 6
    2 3 10
    1 8 5
    2 5 10
    2 4 5
    1 7 9
    2 7 9
    2 10 5


    Sample Output
    Case #1:
    0
    0
    0
    0
    2
    4
    3
    3
    2
    3
    4


    Source
    2015 ACM/ICPC Asia Regional Shenyang Online

    解题:树链剖分

    逆向操作,把删边视为加边,除去删除的那些边,玩树链剖分,首先,你得有棵树,没树,什么都是扯淡。

    我们把要删的那些边从图上统统删除,剩下的残图不一定就是树,所以用并查集在残图上找棵树,树的边权都设为1,然后把残图中不在树上的边都加到树上,这样形成环了,那么把环上的树边全部置0.

    现在开始删边(实际是加边,因为逆序操作)和查询,是的,逆序的,每次加边,就把形成的环,环上的树边都置成0,查询就查询这条路径上的边权和即可

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <set>
      4 #include <algorithm>
      5 #include <cstring>
      6 using namespace std;
      7 typedef pair<int,int> PII;
      8 const int maxn = 200010;
      9 struct arc {
     10     int to,next;
     11     arc(int x = 0,int y = -1) {
     12         to = x;
     13         next = y;
     14     }
     15 } e[maxn<<1];
     16 struct node {
     17     int lt,rt,sum,lazy;
     18 } tree[maxn<<2];
     19 int head[maxn],tot;
     20 void add(int u,int v) {
     21     e[tot] = arc(v,head[u]);
     22     head[u] = tot++;
     23 }
     24 inline void pushup(int v) {
     25     tree[v].sum = tree[v<<1].sum + tree[v<<1|1].sum;
     26 }
     27 inline void pushdown(int v) {
     28     if(~tree[v].lazy) {
     29         tree[v<<1].sum = (tree[v<<1].rt - tree[v<<1].lt + 1)*tree[v].lazy;
     30         tree[v<<1].lazy = tree[v].lazy;
     31         tree[v<<1|1].sum = (tree[v<<1|1].rt - tree[v<<1|1].lt + 1)*tree[v].lazy;
     32         tree[v<<1|1].lazy = tree[v].lazy;
     33         tree[v].lazy = -1;
     34     }
     35 }
     36 void build(int lt,int rt,int v) {
     37     tree[v].lt = lt;
     38     tree[v].rt = rt;
     39     tree[v].lazy = -1;
     40     if(lt == rt) {
     41         tree[v].sum = 1;
     42         return;
     43     }
     44     int mid = (lt + rt)>>1;
     45     build(lt,mid,v<<1);
     46     build(mid + 1,rt,v<<1|1);
     47     pushup(v);
     48 }
     49 void update(int lt,int rt,int val,int v) {
     50     if(lt <= tree[v].lt && rt >= tree[v].rt) {
     51         tree[v].sum = (tree[v].rt - tree[v].lt + 1)*val;
     52         tree[v].lazy = val;
     53         return;
     54     }
     55     pushdown(v);
     56     if(lt <= tree[v<<1].rt) update(lt,rt,val,v<<1);
     57     if(rt >= tree[v<<1|1].lt) update(lt,rt,val,v<<1|1);
     58     pushup(v);
     59 }
     60 int query(int lt,int rt,int v) {
     61     if(lt == tree[v].lt && rt == tree[v].rt) return tree[v].sum;
     62     pushdown(v);
     63     int mid = (tree[v].lt + tree[v].rt)>>1;
     64     if(rt <= mid) return query(lt,rt,v<<1);
     65     if(lt > mid) return query(lt,rt,v<<1|1);
     66     return query(lt,mid,v<<1) + query(mid + 1,rt,v<<1|1);
     67 }
     68 int fa[maxn],dep[maxn],top[maxn],siz[maxn],son[maxn],loc[maxn],cnt;
     69 void FindHeavyEdge(int u,int father,int depth) {
     70     fa[u] = father;
     71     dep[u] = depth;
     72     siz[u] = 1;
     73     son[u] = -1;
     74     for(int i = head[u]; ~i; i = e[i].next) {
     75         if(e[i].to == father) continue;
     76         FindHeavyEdge(e[i].to,u,depth + 1);
     77         siz[u] += siz[e[i].to];
     78         if(son[u] == -1 || siz[son[u]] < siz[e[i].to])
     79             son[u] = e[i].to;
     80     }
     81 }
     82 void ConnectHeavyEdge(int u,int ancestor) {
     83     top[u] = ancestor;
     84     loc[u] = ++cnt;
     85     if(son[u] != -1) ConnectHeavyEdge(son[u],ancestor);
     86     for(int i = head[u]; ~i; i = e[i].next) {
     87         if(e[i].to == fa[u] || e[i].to == son[u]) continue;
     88         ConnectHeavyEdge(e[i].to,e[i].to);
     89     }
     90 }
     91 void UPDATE(int u,int v,int val = 0) {
     92     while(top[u] != top[v]) {
     93         if(dep[top[u]] < dep[top[v]]) swap(u,v);
     94         update(loc[top[u]],loc[u],val,1);
     95         u = fa[top[u]];
     96     }
     97     if(u == v) return;
     98     if(dep[u] > dep[v]) swap(u,v);
     99     update(loc[son[u]],loc[v],val,1);
    100 }
    101 int QUERY(int u,int v,int ret = 0) {
    102     while(top[u] != top[v]) {
    103         if(dep[top[u]] < dep[top[v]]) swap(u,v);
    104         ret += query(loc[top[u]],loc[u],1);
    105         u = fa[top[u]];
    106     }
    107     if(u == v) return ret;
    108     if(dep[u] > dep[v]) swap(u,v);
    109     return ret + query(loc[son[u]],loc[v],1);
    110 }
    111 int u,v,ans[maxn],uf[maxn],op[maxn],x[maxn],y[maxn];
    112 bool used[maxn];
    113 int Find(int x) {
    114     if(x != uf[x]) uf[x] = Find(uf[x]);
    115     return uf[x];
    116 }
    117 multiset<PII>S,V;
    118 int main() {
    119     int kase,n,m,q,cs = 1;
    120     scanf("%d",&kase);
    121     while(kase--) {
    122         S.clear();
    123         V.clear();
    124         scanf("%d%d%d",&n,&m,&q);
    125         for(int i = tot = cnt = 0; i < m; ++i) {
    126             scanf("%d%d",&u,&v);
    127             if(u > v) swap(u,v);
    128             S.insert(PII(u,v));
    129         }
    130         for(int i = 0; i <= n; ++i) {
    131             head[i] = -1;
    132             used[i] = false;
    133             uf[i] = i;
    134         }
    135         for(int i = 0; i < q; ++i) {
    136             scanf("%d%d%d",op + i,x + i,y + i);
    137             if(x[i] > y[i]) swap(x[i],y[i]);
    138             if(op[i] == 1) S.erase(S.find(PII(x[i],y[i])));
    139         }
    140         for(auto &it:S) {
    141             int a = Find(it.first),b = Find(it.second);
    142             if(a != b) {
    143                 V.insert(it);
    144                 add(it.first,it.second);
    145                 add(it.second,it.first);
    146                 uf[a] = b;
    147             }
    148         }
    149         FindHeavyEdge(1,0,0);
    150         ConnectHeavyEdge(1,1);
    151         build(1,cnt,1);
    152         for(auto &it:S)
    153             if(V.find(it) == V.end()) UPDATE(it.first,it.second);
    154         for(int i = q-1; i >= 0; --i)
    155             if(op[i] == 1) UPDATE(x[i],y[i]);
    156             else if(op[i] == 2) ans[i] = QUERY(x[i],y[i]);
    157         printf("Case #%d:
    ",cs++);
    158         for(int i = 0; i < q; ++i)
    159             if(op[i] == 2) printf("%d
    ",ans[i]);
    160     }
    161     return 0;
    162 }
    View Code
  • 相关阅读:
    【自动化测试】rf+selenium中解决for计数嵌套循环问题
    【自动化测试】RF链接数据库12c遇到的问题总结
    【自动化测试】关于如何管理规范整个团队的想法(1)
    python爬虫--基本流程
    python爬虫--理论
    [工具箱]一键优化Windows
    [工具箱]禁用Windows系统更新做了哪些操作?
    有人说要节能,有人说要耗能
    让攻击挖矿耗能的攻击者闭嘴的方法是?
    POC挖矿没有前途
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4889578.html
Copyright © 2011-2022 走看看