poj 3694 Network

来源:互联网 发布:知乎数据挖掘考研 编辑:程序博客网 时间:2024/05/17 22:54

类型:图连通性

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

来源:2008 Asia Hefei Regional Contest Online by USTC

思路:Tarjan 算法搜索得到一颗树,记录每个节点的父节点及该节点的搜索深度,同时记录桥【通过记录末端点来记录桥--一一对应】

对于新添加的边,容易知道从这两个端点往上到其最近公共祖先路径上的桥会消除

通过端点不断向上删除桥【标记清除】

// poj 3694 Network// wa wa wa ac 9616K 1000MS#include <iostream>#include <string>#include <cstring>#include <cstdio>using namespace std;#define clr(a,b) memset(a,b,sizeof(a))#define MAXN 110000#define MAXM 410000bool vis[MAXN];int F, R, q, bri_num, cnt, num;int step[MAXN], father[MAXN], dep[MAXN], low[MAXN], head[MAXN], bridge[MAXN];struct edge {int v, nxt, id;}e[MAXM];void addedge(int u, int v, int id) {    e[cnt].v = v;    e[cnt].id = id;    e[cnt].nxt = head[u];    head[u] = cnt++;}void dfs(int fa, int u,int id, int d) {    father[u] = fa;    dep[u] = d;for(int i = head[u]; i != -1; i = e[i].nxt) {int v = e[i].v;if(e[i].id != id) {if(!vis[v]) {vis[v] = true;step[v] = low[v] = (++num);dfs(u, v, e[i].id, d + 1);low[u] = min(low[u], low[v]);}elselow[u] = min(low[u],step[v]);if(low[v] > step[u])    bridge[v] = 1, bri_num++;}}}void LCA(int x, int y) {    if(dep[x] < dep[y])        swap(x, y);    while(dep[x] != dep[y]) {        if(bridge[x] == 1)            bridge[x] = 0,  bri_num--;        x = father[x];    }    while(x != y) {        if(bridge[x] == 1)            bridge[x] = 0, bri_num--;        x = father[x];        if(bridge[y] == 1)            bridge[y] = 0, bri_num--;        y = father[y];    }}void init() {int i, u, v;clr(head, -1);clr(vis, false);clr(dep, 0);clr(bridge, 0);for(i = 0; i != R; ++i) {scanf("%d %d", &u, &v);addedge(u, v, i);addedge(v, u, i);}step[1] = low[1] = num = 1;cnt = bri_num = 0;vis[1] = true;}int main() {    int cas = 1;while(scanf("%d%d",&F,&R) == 2, F || R) {init();        dfs(0, 1, 1, 0);        scanf("%d", &q);        int x, y;        printf("Case %d:\n", cas++);        for(int i = 0; i < q; ++i) {            scanf("%d %d", &x, &y);            LCA(x, y);            printf("%d\n", bri_num);        }        printf("\n");}    return 0;}



原创粉丝点击