zoukankan      html  css  js  c++  java
  • Network(POJ3694+边双连通分量+LCA)

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

    题目:

    题意:给你一个n个点m条边的无向连通图,进行q次操作,每次操作在u和v之间加一条边,问每次操作之后“桥”的数量。

    思路:先tarjan预处理出初始状态“桥”的数量cnt,并进行标记,对于每次操作,进行lca查询,将u和v之间的桥的数量num统计好,并消除标记,结果就是cnt-num。

    代码实现如下:

      1 #include <set>
      2 #include <map>
      3 #include <queue>
      4 #include <stack>
      5 #include <cmath>
      6 #include <bitset>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstdlib>
     11 #include <cstring>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 
     16 typedef long long ll;
     17 typedef pair<ll, ll> pll;
     18 typedef pair<ll, int> pli;
     19 typedef pair<int, ll> pil;;
     20 typedef pair<int, int> pii;
     21 typedef unsigned long long ull;
     22 
     23 #define lson i<<1
     24 #define rson i<<1|1
     25 #define bug printf("*********
    ");
     26 #define FIN freopen("D://code//in.txt", "r", stdin);
     27 #define debug(x) cout<<"["<<x<<"]" <<endl;
     28 #define IO ios::sync_with_stdio(false),cin.tie(0);
     29 
     30 const double eps = 1e-8;
     31 const int mod = 10007;
     32 const int maxn = 1e5 + 7;
     33 const double pi = acos(-1);
     34 const int inf = 0x3f3f3f3f;
     35 const ll INF = 0x3f3f3f3f3f3f3f;
     36 
     37 int n, m, q, u, v, tot, cnt, num;
     38 int head[maxn], dfn[maxn], low[maxn], vis[maxn], pre[maxn], c[maxn];
     39 
     40 struct edge {
     41     int v, next;
     42 }ed[maxn<<2];
     43 
     44 void init() {
     45     tot = cnt = num = 0;
     46     memset(c, 0, sizeof(c));
     47     memset(vis, 0, sizeof(vis));
     48     memset(dfn, 0, sizeof(dfn));
     49     memset(low, 0, sizeof(low));
     50     memset(head, -1, sizeof(head));
     51     for(int i = 1; i < maxn; i++) {
     52         pre[i] = i;
     53     }
     54 }
     55 
     56 void addedge(int u, int v) {
     57     ed[tot].v = v;
     58     ed[tot].next = head[u];
     59     head[u] = tot++;
     60     ed[tot].v = u;
     61     ed[tot].next = head[v];
     62     head[v] = tot++;
     63 }
     64 
     65 void tarjan(int x, int fa) {
     66     dfn[x] = low[x] = ++num;
     67     c[x] = 1;
     68     for(int i = head[x]; ~i; i = ed[i].next) {
     69         int v = ed[i].v;
     70         if(!c[v]) {
     71             tarjan(v, x);
     72             pre[v] = x;
     73             low[x] = min(low[x], low[v]);
     74             if(low[v] > dfn[x]) {
     75                 vis[v] = 1;
     76                 cnt++;
     77             }
     78         } else if(c[v] == 1 && v != fa) {
     79             low[x] = min(low[x], dfn[v]);
     80         }
     81     }
     82     c[x] = 2;
     83 }
     84 
     85 int cut(int x, int y) {
     86     int cnt = 0;
     87     while(dfn[x] > dfn[y]) {
     88         if(vis[x]) {
     89             cnt++;
     90             vis[x] = 0;
     91         }
     92         x = pre[x];
     93     }
     94     while(dfn[y] > dfn[x]) {
     95         if(vis[y]) {
     96             cnt++;
     97             vis[y] = 0;
     98         }
     99         y = pre[y];
    100     }
    101     while(x != y) {
    102         if(vis[x]) {
    103             cnt++;
    104             vis[x] = 0;
    105         }
    106         if(vis[y]) {
    107             cnt++;
    108             vis[y] = 0;
    109         }
    110         x = pre[x];
    111         y = pre[y];
    112     }
    113     return cnt;
    114 }
    115 
    116 int main() {
    117     //FIN;
    118     int icase = 0;
    119     while(~scanf("%d%d", &n, &m)) {
    120         if(n == 0 && m == 0) break;
    121         init();
    122         for(int i = 1; i <= m; i++) {
    123             scanf("%d%d", &u, &v);
    124             addedge(u, v);
    125         }
    126         printf("Case %d:
    ", ++icase);
    127         tarjan(1, 0);
    128         scanf("%d", &q);
    129         while(q--) {
    130             scanf("%d%d", &u, &v);
    131             cnt -= cut(u, v);
    132             printf("%d
    ", cnt);
    133         }
    134         printf("
    ");
    135     }
    136     return 0;
    137 }
  • 相关阅读:
    Git从远程分支创建本地分支
    Git删除远程分支
    git查看某次commit的修改
    translatesAutoresizingMaskIntoConstraints
    微信公众平台开发实战Java版之如何网页授权获取用户基本信息
    Oracle中的instr()函数 详解及应用
    eclipse查看方法被那些代码调用open call hierarchy
    Eclipse怎么全局搜索和替换(整个项目)
    Java中的final关键字--浅析
    shell脚本-成长之路
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9394704.html
Copyright © 2011-2022 走看看