题意: 添加每条新连接后网络中桥的数目
// 超时 先放着了 ,下次改
//早上这代码超时了 下午改了,代码在下面
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MOD 1000000007
#define maxn 440000
#define maxm 100010
struct Edge{
int to;
int num;
int next;
Edge(){};
Edge(int u,int v){to=u;next=v;}
}E[maxn];
int V[maxm],num;
bool tag[maxn];
int pre[maxm];
int dfst,bcc;
int ans,eg;
void init(int n){
eg=0;
dfst=0;
num=0;
bcc=0;
for(int i=1;i<=n;i++)
V[i]=-1;
}
void add(int u,int v){ // 坑爹 原来原图没有重边的 郁闷 ,这里就耗了不少时间
int e;
for(e=V[u];e!=-1;e=E[e].next)
{
if(v==E[e].to){
tag[E[e].num]=1;return;
}
}
eg++;
E[num].to=v;
E[num].num=eg;
E[num].next=V[u];
V[u]=num++;
E[num].to=u;
E[num].num=eg;
E[num].next=V[v];
V[v]=num++;
}
int dfs(int u,int fa){
int lowu;
lowu=pre[u]=++dfst;
int v,e;
for(e=V[u];e!=-1;e=E[e].next){
v=E[e].to;
if(!pre[v]){
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
if(lowv>pre[u]&&!tag[E[e].num]){
ans++;
}
}
else if(v!=fa) lowu=min(lowu,pre[v]);
}
return lowu;
}
int main()
{
int n,m,Q;
int u,v;
int i,j=1;
while(scanf("%d %d",&n,&m),n|m){
init(n);
for(i=1;i<=m;i++){
scanf("%d %d",&u,&v);
tag[i]=0;
add(u,v);
}
printf("Case %d:
",j++);
scanf("%d",&Q); for(i=1;i<=Q;i++) tag[i+m]=0;
while(Q--){
scanf("%d %d",&u,&v);
add(u,v);
for(i=1;i<=n;i++) pre[i]=0;
ans=0;
dfst=0;
dfs(1,0);
printf("%d
",ans);
}
printf("
");
}
return 0;
}
// 在原来的基础上 执行一次dfs 然就找两点的lca 我不愿去缩点 啥的, 网上看到一个不错的,就用了
// 就是先让 x,y达到同一深度 然后回走 直到碰面 边上遇到桥就标记删除
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MOD 1000000007
#define maxn 440000
#define maxm 100010
struct Edge{
int to;
// int num;
int next;
Edge(){};
Edge(int u,int v){to=u;next=v;}
}E[maxn];
int V[maxm],num;
bool tag[maxm];
int fa[maxm];
int pre[maxm],low;
int dfst;
int ans;
void init(int n){
dfst=0;
num=0;
ans=0;
for(int i=1;i<=n;i++){
V[i]=-1;
pre[i]=0;
tag[i]=0;
}
}
void add(int u,int v){
E[num].to=v;
// E[num].num=m;
E[num].next=V[u];
V[u]=num++;
E[num].to=u;
// E[num].num=m;
E[num].next=V[v];
V[v]=num++;
}
int dfs(int u,int dp){
int lowu=pre[u]=dp;
int v,e;
for(e=V[u];e!=-1;e=E[e].next){
v=E[e].to;
if(!pre[v]){
fa[v]=u;
// printf("?%d %d %d
",v,u,fa[v]);
int lowv=dfs(v,dp+1);
lowu=min(lowu,lowv);
if(lowv>pre[u]){
ans++;
tag[v]=true; //printf("%d",v);
}
}
else if(v!=fa[u]) lowu=min(lowu,pre[v]);
}
// printf("%d %d ",u,fa[u]);
return lowu;
}
void lca(int x,int y){
if(pre[x]>pre[y]) swap(x,y);
while(pre[y]!=pre[x]){
if(tag[y]){ans--;tag[y]=false;}
y=fa[y];
}
while(x!=y){
if(tag[x]){ans--;tag[x]=false;}
if(tag[y]){ans--;tag[y]=false;}
x=fa[x];y=fa[y];
}
}
int main()
{
int n,m,Q;
int u,v;
int i,j=1;
while(scanf("%d %d",&n,&m),n|m){
init(n);
for(i=1;i<=m;i++){
scanf("%d %d",&u,&v);
add(u,v);
}
fa[1]=1;
dfs(1,1);
printf("Case %d:
",j++);
scanf("%d",&Q);// for(i=1;i<=Q;i++) tag[i+m]=0;
while(Q--){
scanf("%d %d",&u,&v);
lca(u,v);
printf("%d
",ans);
}
printf("
");
}
return 0;
}