首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络协议 >

POJ 3694 network 无向图求桥 手记栈版tarjan

2012-09-22 
POJ3694network无向图求桥手写栈版tarjan这题以前做过大意就是给出一个无向图,然后每次询问加一条边,然后

POJ 3694 network 无向图求桥 手写栈版tarjan

这题以前做过

大意就是给出一个无向图,然后每次询问加一条边,然后输出当前图中剩余的桥的个数

大概做法就是先tarjan把桥都弄出来,然后每次加边就裸求LCA。

不过很蛋疼的事情就是在HDU上会爆栈,这很贱,所以有必要弄个手写栈版得tarjan


#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <cmath>#include <queue>#include <map>#include <set>#define MAXN 111111#define MAXM 555555#define INF 1000000011#define lch(x) x<<1#define rch(x) x<<1|1#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define eps 1e-7using namespace std;struct Edge{    int v, next;}edge[MAXM];int head[MAXN], e, n, m;int dfn[MAXN], low[MAXN], fa[MAXN];int index, tmpdfn, vis[MAXN];int cnt, bridge[MAXN];int st[MAXN];void init(){    e = index = cnt = 0;    memset(vis, 0, sizeof(vis));    memset(low, 0, sizeof(low));    memset(dfn, 0, sizeof(dfn));    memset(bridge, 0, sizeof(bridge));    memset(head, -1, sizeof(head));    for(int i = 1; i <= n; i++) fa[i] = i;}void add(int u, int v){    edge[e].v = v;    edge[e].next = head[u];    head[u] = e++;}void tarjan(){    int top = 0;    st[++top] = 1;    while(top)    {        int u = st[top];        if(!vis[u])        {            dfn[u] = low[u] = ++index;            vis[u] = 1;        }        int i;        for(i = head[u]; i != -1; i = edge[i].next)        {            int v = edge[i].v;            if(!vis[v])            {                fa[v] = u;                break;            }            else if(vis[v] == 1 && v != fa[u]) low[u] = min(low[u], dfn[v]);        }        if(i == -1 && top > 1)        {            low[st[top - 1]] = min(low[u], low[st[top - 1]]);            if(low[u] > dfn[st[top - 1]])            {                bridge[u] = 1;                cnt++;            }        }        if(i == -1)        {            vis[u] = 2;            top--;        }        else st[++top] = edge[i].v;    }}void LCA(int u, int v){    while(dfn[u] > dfn[v])    {        if(bridge[u]) cnt--, bridge[u] = 0;        u = fa[u];    }    while(dfn[v] > dfn[u])    {        if(bridge[v]) cnt--, bridge[v] = 0;        v = fa[v];    }    while(u != v)    {        if(bridge[u]) cnt--, bridge[u] = 0;        u = fa[u];        if(bridge[v]) cnt--, bridge[v] = 0;        v = fa[v];    }}void gao(){    int q;    scanf("%d", &q);    while(q--)    {       int x, y;       scanf("%d%d", &x, &y);       LCA(x, y);       printf("%d\n", cnt);    }    printf("\n");}int main(){    int cas = 0;    while(scanf("%d%d", &n, &m) != EOF)    {        if(!n && !m) break;        init();        int x, y;        while(m--)        {            scanf("%d%d", &x, &y);            add(x, y);            add(y, x);        }        tarjan();        printf("Case %d:\n", ++cas);        gao();    }    return 0;}


热点排行