Monday, December 10, 2018

[Spoj] ONBRIDGE - Online Bridge Searching

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : ONBRIDGE - Online Bridge Searching
Source            : Spoj
Category          : Graph Theory
Algorithm         : Online Bridge Searching
Verdict           : Accepted
#include "bits/stdc++.h"
 
using namespace std;
 
inline int read()          { int a; scanf("%d", &a); return a; }
 
static const int maxn = 5e4 + 5;
 
int n,           // number of nodes
    bridge,      // total bridge after each addition of edge
    m,           // number of edge
    bcc[maxn],   // bcc number of i'th node
    comp[maxn],  // connected component no of i'th node
    link[maxn],  // link of parent node
    sz[maxn];    // size of connected component where i'th node associated
 
void init()
{
    for(int i = 0; i < maxn; i++)
    {
       bcc[i] = comp[i] = i;  // BCC and CC of a node, Initially all are isolate.
       link[i] = -1;          // Link of the parent in CC
       sz[i] = 1;             // Size of a CC
    }
    bridge = 0;
}
 
// Output the BCC of a node
int getBCC(int a)
{
    if (a == -1) return -1;
    if (bcc[a] == a) return a;
    else return bcc[a] = getBCC(bcc[a]);
}
 
// Output the root of the component where a is.
int getCOMP(int a)
{
    if (comp[a] == a) return a;
    else return comp[a] = getCOMP(comp[a]);
}
 
// Merging two path, a->LCA, b->LCA
int cs = 0, vis[maxn];
void mergePath(int a, int b)
{
    cs++;
    a = getBCC(a);
    b = getBCC(b);
    vector <int> va, vb;
    int lca = -1;
    while(1)
    {
        if (a != -1)
        {
            a = getBCC(a);
            va.emplace_back(a);
            if (vis[a] == cs)
            {
                lca = a;
                break;
            }
            vis[a] = cs;
            a = link[a];
        }
        if (b != -1)
        {
            b = getBCC(b);
            vb.emplace_back(b);
            if (vis[b] == cs)
            {
                lca = b;
                break;
            }
            vis[b] = cs;
            b = link[b];
        }
    }
    for (int it : va)
    {
        bcc[it] = lca;    // compressing in same BCC
        if (it == lca) break;
        bridge--;
    }
    for (int it : vb)
    {
        bcc[it] = lca;   // compressing in same BCC
        if (it == lca) break;
        bridge--;
    }
}
 
// This reverses the edge of A to root of the connected component
void makeRoot(int a)
{
    int root = a, child = -1;
    while (a != -1)
    {
        int p = getBCC(link[a]);
        link[a] = child;
        comp[a] = root;
        child = a;
        a = p;
    }
    sz[root] = sz[child];
}
 
void addEdge(int a, int b)
{
    a = getBCC(a);
    b = getBCC(b);
    if (a == b) return;  // Case 1
    int u = getCOMP(a);
    int v = getCOMP(b);
    if (u != v)          // Case 2
    {
        bridge++;
        if (sz[u] > sz[v])
        {
            swap(a, b);
            swap(u, v);
        }
        makeRoot(a);
        link[a] = comp[a] = b;
        sz[v] += sz[a];
    }
    else mergePath(a, b);  // Case 3
}
 
int main()
{
    //freopen("in.txt", "r", stdin);
 
    int tc = read();
    for (int tcase = 1; tcase <= tc; tcase++)
    {
        init();
        n = read();
        m = read();
        for (int e = 1; e <= m; e++)
        {
            int u = read(), v = read();
            addEdge(u, v);
            printf("%d\n", bridge);
        }
    }
}
 

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.