这题以前做过
大意就是给出一个无向图,然后每次询问加一条边,然后输出当前图中剩余的桥的个数
大概做法就是先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-7
using namespace std;
struct Edge
{
int v, next;
}edge[MAXM];
int head[MAXN], e, n, m;
int dfn[MAXN], low[MAXN], fa[MAXN], Dfn[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(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(!dfn[u])
{
dfn[u] = low[u] = ++index;
Dfn[u] = Dfn[fa[u]] + 1;
}
int i;
for(i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if(!dfn[v])
{
fa[v] = u;
break;
}
else if(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) 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;
if(bridge[v]) cnt--, bridge[v] = 0;
u = fa[u];
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;
}