• [POJ3694]Network(LCA, 割边, 桥)


    题目链接:http://poj.org/problem?id=3694

    题意:给一张图,每次加一条边,问割边数量。

    tarjan先找出所有割边,并且记录每个点的父亲和来自于哪一条边,然后询问的时候从两个点向上找lca,沿途更新割边数量和割边状态即可。

    AC代码

      1 /*
      2             ━━━━━┒ギリギリ♂ eye!
      3             ┓┏┓┏┓┃キリキリ♂ mind!
      4             ┛┗┛┗┛┃\○/
      5             ┓┏┓┏┓┃ /
      6             ┛┗┛┗┛┃ノ)
      7             ┓┏┓┏┓┃
      8             ┛┗┛┗┛┃
      9             ┓┏┓┏┓┃
     10             ┛┗┛┗┛┃
     11             ┓┏┓┏┓┃
     12             ┛┗┛┗┛┃
     13             ┓┏┓┏┓┃
     14             ┃┃┃┃┃┃
     15             ┻┻┻┻┻┻
     16 */
     17 #include                     <algorithm>
     18 #include                     <iostream>
     19 #include                     <iomanip>
     20 #include                     <cstring>
     21 #include                     <climits>
     22 #include                     <complex>
     23 #include                     <fstream>
     24 #include                     <cassert>
     25 #include                     <cstdio>
     26 #include                     <bitset>
     27 #include                     <vector>
     28 #include                     <deque>
     29 #include                     <queue>
     30 #include                     <stack>
     31 #include                     <ctime>
     32 #include                     <set>
     33 #include                     <map>
     34 #include                     <cmath>
     35 using namespace             std;
     36 #define fr                     first
     37 #define sc                     second
     38 #define cl                     clear
     39 #define BUG                 puts("here!!!")
     40 #define W(a)                 while(a--)
     41 #define pb(a)                 push_back(a)
     42 #define Rint(a)             scanf("%d", &a)
     43 #define Rll(a)                 scanf("%lld", &a)
     44 #define Rs(a)                 scanf("%s", a)
     45 #define Cin(a)                 cin >> a
     46 #define FRead()             freopen("in", "r", stdin)
     47 #define FWrite()             freopen("out", "w", stdout)
     48 #define Rep(i, len)         for(int i = 0; i < (len); i++)
     49 #define For(i, a, len)         for(int i = (a); i < (len); i++)
     50 #define Cls(a)                 memset((a), 0, sizeof(a))
     51 #define Clr(a, x)             memset((a), (x), sizeof(a))
     52 #define Full(a)             memset((a), 0x7f7f, sizeof(a))
     53 #define lp                    p << 1
     54 #define rp                    p << 1 | 1
     55 #define pi                    3.14159265359
     56 #define RT                    return
     57 typedef    long long             LL;
     58 typedef    long double         LD;
     59 typedef    unsigned long long     ULL;
     60 typedef    pair<int, int>         pii;
     61 typedef    pair<string, int>     psi;
     62 typedef    map<string, int>     msi;
     63 typedef    vector<int>         vi;
     64 typedef    vector<LL>             vl;
     65 typedef    vector<vl>             vvl;
     66 typedef    vector<bool>         vb;
     67 
     68 inline bool scan_d(int &num) {
     69     char in;bool IsN=false;
     70     in=getchar();
     71     if(in==EOF) return false;
     72     while(in!='-'&&(in<'0'||in>'9')) in=getchar();
     73     if(in=='-'){ IsN=true;num=0;}
     74     else num=in-'0';
     75     while(in=getchar(),in>='0'&&in<='9'){
     76             num*=10,num+=in-'0';
     77     }
     78     if(IsN) num=-num;
     79     return true;
     80 }
     81 
     82 const int maxn = 200010;
     83 const int maxm = 900020;
     84 
     85 typedef struct Edge {
     86     int idx, v;
     87     Edge() {}
     88     Edge(int vv, int ii) : v(vv), idx(ii) {}
     89 }Edge;
     90 
     91 int n, m, q, cnt, b;
     92 int depth[maxn], fa[maxn], vis[maxn];
     93 int dfn[maxn], low[maxn], pbr[maxm];
     94 vector<Edge> G[maxn];
     95 bool bri[maxm];
     96 void dfs(int u, int p, int d) {
     97     fa[u] = p; depth[u] = d;
     98     Rep(i, G[u].size()) {
     99         int v = G[u][i].v;
    100         if(!vis[v]) {
    101             vis[v] = 1;
    102             dfs(v, u, d+1);
    103         }
    104     }
    105 }
    106 
    107 void tarjan(int u, int p, int d, int pe) {
    108     low[u] = dfn[u] = d;
    109     pbr[u] = pe;
    110     Rep(i, G[u].size()) {
    111         int idx = G[u][i].idx;
    112         int v = G[u][i].v;
    113         if(!dfn[v]) {
    114             tarjan(v, u, d+1, idx);
    115             low[u] = min(low[u], low[v]);
    116             if(low[v] > dfn[u]) bri[idx] = 1;
    117         }
    118         else if(v != p) low[u] = min(low[u], dfn[v]);
    119     }
    120 }
    121 
    122 void lca(int u, int v) {
    123     while(depth[u] > depth[v]) {
    124         if(bri[pbr[u]]) {
    125             bri[pbr[u]] = 0; b--;
    126         }
    127         u = fa[u];
    128     }
    129     while(depth[v] > depth[u]) {
    130         if(bri[pbr[v]]) {
    131             bri[pbr[v]] = 0; b--;
    132         }
    133         v = fa[v];
    134     }
    135     while(u != v) {
    136         if(bri[pbr[u]]) {
    137             bri[pbr[u]] = 0; b--;
    138         }
    139         u = fa[u];
    140         if(bri[pbr[v]]) {
    141             bri[pbr[v]] = 0; b--;
    142         }
    143         v = fa[v];
    144     }
    145 }
    146 
    147 int main() {
    148     // FRead();
    149     int u, v, _ = 1;
    150     while(~scan_d(n) && ~scan_d(m) && n + m) {
    151         Cls(depth); Cls(vis); Cls(fa); Cls(pbr);
    152         Cls(dfn); Cls(low); Cls(bri); b = 0;
    153         Rep(i, n+5) G[i].cl();
    154         Rep(i, m) {
    155             scan_d(u); scan_d(v);
    156             G[u].pb(Edge(v, cnt++)); G[v].pb(Edge(u, cnt++));
    157         }
    158         dfs(1, 1, 0); tarjan(1, 1, 0, 0);
    159         scan_d(q);
    160         printf("Case %d:
    ", _++);
    161         For(i, 1, cnt+1) if(bri[i]) b++;
    162         W(q) {
    163             scan_d(u); scan_d(v);
    164             lca(u, v);
    165             printf("%d
    ", b);
    166         }
    167     }
    168     RT 0;
    169 }

    第一次TLE了,因为窝把erase的复杂度想象成了O(lgn)…

      1 /*
      2             ━━━━━┒ギリギリ♂ eye!
      3             ┓┏┓┏┓┃キリキリ♂ mind!
      4             ┛┗┛┗┛┃\○/
      5             ┓┏┓┏┓┃ /
      6             ┛┗┛┗┛┃ノ)
      7             ┓┏┓┏┓┃
      8             ┛┗┛┗┛┃
      9             ┓┏┓┏┓┃
     10             ┛┗┛┗┛┃
     11             ┓┏┓┏┓┃
     12             ┛┗┛┗┛┃
     13             ┓┏┓┏┓┃
     14             ┃┃┃┃┃┃
     15             ┻┻┻┻┻┻
     16 */
     17 #include                     <algorithm>
     18 #include                     <iostream>
     19 #include                     <iomanip>
     20 #include                     <cstring>
     21 #include                     <climits>
     22 #include                     <complex>
     23 #include                     <fstream>
     24 #include                     <cassert>
     25 #include                     <cstdio>
     26 #include                     <bitset>
     27 #include                     <vector>
     28 #include                     <deque>
     29 #include                     <queue>
     30 #include                     <stack>
     31 #include                     <ctime>
     32 #include                     <set>
     33 #include                     <map>
     34 #include                     <cmath>
     35 using namespace             std;
     36 #define fr                     first
     37 #define sc                     second
     38 #define cl                     clear
     39 #define BUG                 puts("here!!!")
     40 #define W(a)                 while(a--)
     41 #define pb(a)                 push_back(a)
     42 #define Rint(a)             scanf("%d", &a)
     43 #define Rll(a)                 scanf("%lld", &a)
     44 #define Rs(a)                 scanf("%s", a)
     45 #define Cin(a)                 cin >> a
     46 #define FRead()             freopen("in", "r", stdin)
     47 #define FWrite()             freopen("out", "w", stdout)
     48 #define Rep(i, len)         for(int i = 0; i < (len); i++)
     49 #define For(i, a, len)         for(int i = (a); i < (len); i++)
     50 #define Cls(a)                 memset((a), 0, sizeof(a))
     51 #define Clr(a, x)             memset((a), (x), sizeof(a))
     52 #define Full(a)             memset((a), 0x7f7f, sizeof(a))
     53 #define lp                    p << 1
     54 #define rp                    p << 1 | 1
     55 #define pi                    3.14159265359
     56 #define RT                    return
     57 typedef    long long             LL;
     58 typedef    long double         LD;
     59 typedef    unsigned long long     ULL;
     60 typedef    pair<int, int>         pii;
     61 typedef    pair<string, int>     psi;
     62 typedef    map<string, int>     msi;
     63 typedef    vector<int>         vi;
     64 typedef    vector<LL>             vl;
     65 typedef    vector<vl>             vvl;
     66 typedef    vector<bool>         vb;
     67 
     68 inline bool scan_d(int &num) {
     69     char in;bool IsN=false;
     70     in=getchar();
     71     if(in==EOF) return false;
     72     while(in!='-'&&(in<'0'||in>'9')) in=getchar();
     73     if(in=='-'){ IsN=true;num=0;}
     74     else num=in-'0';
     75     while(in=getchar(),in>='0'&&in<='9'){
     76             num*=10,num+=in-'0';
     77     }
     78     if(IsN) num=-num;
     79     return true;
     80 }
     81 
     82 const int maxn = 100010;
     83 const int maxm = 300020;
     84 typedef struct Bridge {
     85     int u, v;
     86     Bridge() {}
     87     Bridge(int uu, int vv) : u(uu), v(vv) { if(u > v) swap(u, v); }
     88     bool operator<(Bridge y) {
     89         if(u == y.u) return v < y.v;
     90         return u < y.u;
     91     }
     92 }Bridge;
     93 
     94 int n, m, q;
     95 int ufs[maxn];
     96 int depth[maxn], fa[maxn], vis[maxn];
     97 int dfn[maxn], low[maxn];
     98 vi G[maxn];
     99 vector<Bridge> b;
    100 vector<Bridge>::iterator it;
    101 
    102 int find(int x) {
    103     return x == ufs[x] ? x : ufs[x] = find(ufs[x]);
    104 }
    105 
    106 void unite(int x, int y) {
    107     x = find(x);
    108     y = find(y);
    109     if(x != y) ufs[y] = x;
    110 }
    111 
    112 void dfs(int u, int p, int d) {
    113     fa[u] = p; depth[u] = d;
    114     Rep(i, G[u].size()) {
    115         int v = G[u][i];
    116         if(!vis[v]) {
    117             vis[v] = 1;
    118             dfs(v, u, d+1);
    119         }
    120     }
    121 }
    122 
    123 
    124 void tarjan(int u, int p, int d) {
    125     low[u] = dfn[u] = d;
    126     Rep(i, G[u].size()) {
    127         int v = G[u][i];
    128         if(!dfn[v]) {
    129             tarjan(v, u, d+1);
    130             low[u] = min(low[u], low[v]);
    131             if(low[v] > dfn[u]) b.pb(Bridge(u, v));
    132         }
    133         else if(v != p) low[u] = min(low[u], dfn[v]);
    134     }
    135 }
    136 
    137 bool cmp(Bridge x, Bridge y) {
    138     if(x.u == y.u) return x.v < y.v;
    139     return x.u < y.u;
    140 }
    141 
    142 int bs(Bridge x) {
    143     int lo = 0, hi = b.size();
    144     while(lo <= hi) {
    145         int mi = (lo + hi) >> 1;
    146         if(b[mi].u == x.u && b[mi].v == x.v) return mi;
    147         if(cmp(x, b[mi]) > 0) hi = mi - 1;
    148         else lo = mi + 1;
    149     }
    150     if(b[lo].u == x.u && b[lo].v == x.v) return lo;
    151     if(b[hi].u == x.u && b[hi].v == x.v) return hi;
    152     return -1;
    153 }
    154 
    155 void lca(int u, int v) {
    156     while(depth[u] > depth[v]) {
    157         Bridge tmp = Bridge(u, fa[u]);
    158         it = lower_bound(b.begin(), b.end(), tmp);
    159         if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it);
    160         u = fa[u];
    161     }
    162     while(depth[v] > depth[u]) {
    163         Bridge tmp = Bridge(v, fa[v]);
    164         it = lower_bound(b.begin(), b.end(), tmp);
    165         if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it);
    166         v = fa[v];
    167     }
    168     while(u != v) {
    169         Bridge tmp = Bridge(u, fa[u]);
    170         it = lower_bound(b.begin(), b.end(), tmp);
    171         if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it);
    172         tmp = Bridge(v, fa[v]);
    173         it = lower_bound(b.begin(), b.end(), tmp);
    174         if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it);
    175         u = fa[u];
    176         v = fa[v];
    177     }
    178 }
    179 
    180 int main() {
    181     // FRead();
    182     int u, v, _ = 1;
    183     while(~scan_d(n) && ~scan_d(m) && n + m) {
    184         Cls(depth); Cls(vis); Cls(fa);
    185         Cls(dfn); Cls(low); b.cl();
    186         Rep(i, n+5) G[i].cl(), ufs[i] = i;
    187         Rep(i, m) {
    188             scan_d(u); scan_d(v);
    189             G[u].pb(v); G[v].pb(u);
    190         }
    191         dfs(1, 1, 0); tarjan(1, 1, 0);
    192         sort(b.begin(), b.end(), cmp);
    193         scan_d(q);
    194         printf("Case %d:
    ", _++);
    195         W(q) {
    196             scan_d(u); scan_d(v);
    197             Bridge tmp = Bridge(u, v);
    198             it = lower_bound(b.begin(), b.end(), tmp);
    199             if(it != b.end() && it->u == tmp.u && it->v == tmp.v) {
    200                 b.erase(it);
    201                 printf("%d
    ", b.size());
    202                 continue;
    203             }
    204             else {
    205                 lca(u, v);
    206                 printf("%d
    ", b.size());
    207             }
    208         }
    209     }
    210     RT 0;
    211 }
  • 相关阅读:
    python求3的倍数与和
    linux内核优化参数
    ssh 调优参数
    mysql xtarbackup备份脚本
    mysql全库备份数据库脚本
    python json模块
    python函数介绍
    字典常用操作
    python常用字符串操作
    最好的10本适用于初学者阅读的javaScript和jQuery书籍
  • 原文地址:https://www.cnblogs.com/kirai/p/5518615.html
Copyright © 2020-2023  润新知