POJ - 3694 Network (tarjan + lca)

Meaning of the questions: given a free phase diagram, then the newly added edge q times, asked the number of sides in the process of adding the bridge
if and only if no time to edge (u, v) for the branches, it is necessary to meet the dfn (u) <low (v),
i.e. less than u and v turned up above point, it must be able to have one or more edges between the UV is not omitted, because no portion of the ring between them, the bridge
idea: first, we know that after a given a map, keep adding side, the number of bridges will reduce rather than increase
the use of tarjan is shrinking point, a connected component shrunk to a point, then the edge of the connected components will not bridge is
simultaneously finished after condensing point we will find, in fact, newly formed side bridge tree
during the addition, the number of bridges in the connected component if it is not reduced
if u, v at two different communication component, then u, v and its LCA (lowest common ancestor) will be connected into a loop to form a new connected component
number of all of this entire section of the bridge portion will be reduced so connected

Complete code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
typedef long long LL;
typedef pair<int,int>pii;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+10;
const int max_edge = 4e5+5;
struct Edge
{
    int to, next;
}edge[max_edge];
int top, head[maxn];
int pre[maxn];
int id, dfn[maxn], low[maxn];
int cnt;
int bridge[maxn];
int n,m;
void add(int u,int v){
    edge[top].to = v;
    edge[top].next = head[u];
    head[u] = top++;
}
void tarjan(int x,int f){
    // update timestamp 
    DFN [X] = Low [X] ++ = ID;
     for ( int I = head [X]; ~ I; I = Edge [I] .next) {
         int V = Edge [I]. to;
         if (! {DFN [V]) 
            Tarjan (V, X); 
            pre [V] = X; 
            Low [X] = min (Low [V], Low [X]);
             // determination condition bridge 
            if (Low [V]> DFN [X]) { 
                Bridge [V] = . 1 ; 
                CNT ++ ; 
            } 
        } 
        the else  IF (V =!F) { 
            Low [X] = min (Low [X], DFN [V]); 
        } 

    } 
} 
void the init () { 
    Memset (Low, 0 , the sizeof (Low)); 
    Memset (DFN, 0 , the sizeof (DFN )); 
    Memset (Bridge, 0 , the sizeof (Bridge)); 
    Memset (head, - . 1 , the sizeof (head)); 
   CNT = Top = ID = 0 ; 
} 
void LCA ( int U, int V) {
     // enter when the swap, the root assigned to U 
    IF(DFN [U] < DFN [V]) the swap (U, V);
     // side of the bottom of the same height of the first come 
    the while (DFN [U]> DFN [V]) {
         IF (Bridge [U]) CNT -, Bridge [U] = 0 ; 
        U = pre [U]; 
    } 
    // both sides at the same time to go LCA 
    the while (= U! V) {
         IF (Bridge [U]) CNT -, Bridge [U] = 0 ;
         IF (Bridge [V]) CNT -, Bridge [V] = 0 ; 
        U = pre [U]; 
        V = pre [V]; 
    } 
} 
int main () {
     int Case = 0;
    while(cin>>n>>m&&n&&m){
        init();
        for(int i =0;i<m;i++){
            int u,v;
            cin>>u>>v;
            add(u,v),add(v,u);
        }
        tarjan(1,1);
        int q;
        cin>>q;
        cout<<"Case "<<++Case<<":"<<endl;
        while(q--){
            int u,v;
            cin>>u>>v;
            lca(u,v);
            cout<<cnt<<endl;
        }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/Tianwell/p/11328947.html