这里我相信大家肯定都看了题目,如果没看懂的可以先考虑看懂题目意思在看下面代码(我这个人比较懒就不写题目意思了)
思路:首先运行一次tarjan,求出桥和缩点,那么远无向图将缩点为一棵树,树边正好是原来的桥。每次连接两点,看看这两点是不是在同一个缩点内,如果是,那么缩点后的树没任何变化,如果两点属于不同的缩点,那么连接起来,然后找这两个缩点的LCA,,因为从点u到LCA再到点v再到点u,将形成环,里面的树边都会变成不是桥。计数的时候注意,有些树边可能之前已经被标记了,这次再经过不能再标记
----------
如果觉得都看不懂那就请参考一下这个网址:https://blog.csdn.net/zhengnanlee/article/details/22646327
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int SIZE=1000010;
int head[SIZE],ver[SIZE*2],Next[SIZE*2],dfn[SIZE],low[SIZE];
int n,m,tot,num,c[SIZE],dcc,q,l;
int hc[SIZE],vc[SIZE*2],nc[SIZE*2],tc,bi[SIZE],pre[SIZE];
bool bridge[SIZE*2];
void add(int x,int y){
ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
}
void tarjan(int x,int x1)
{
dfn[x]=low[x]=++num;
for(int i=head[x];i;i=Next[i])
{
int y=ver[i];
if(!dfn[y]){
tarjan(y,i);pre[y]=x;
low[x]=min(low[x],low[y]);
if(low[y]>dfn[x]){
bridge[i]=bridge[i^1]=true;
bi[y]=true;
}
}
else if(i!=(x1^1))
low[x]=min(low[x],dfn[y]);
}
}
void dfs(int x)
{
c[x]=dcc;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(c[y]||bridge[i])continue;
dfs(y);
}
}
void add_c(int x,int y){
vc[++tc]=y,nc[tc]=hc[x],hc[x]=tc;//求边数;
}
int lca(int u,int v)
{
int cnt1=0;
while(dfn[u]>dfn[v]){
if(bi[u]){
cnt1++;bi[u]=false;
}u=pre[u];
}
while(dfn[u]<dfn[v]){
if(bi[v]){
cnt1++;bi[v]=false;
}v=pre[v];
}
while(u!=v){
if(bi[u]){
bi[u]=false;cnt1++;
}
if(bi[v]){
bi[v]=false;cnt1++;
}
u=pre[u];v=pre[v];
}return cnt1;
}
void Adjust()
{
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(bi,0,sizeof(bi));
for(int i=1;i<=n;i++)pre[i]=i;
memset(bridge,false,sizeof(bridge));
memset(c,0,sizeof(c));
memset(head,0,sizeof(head));
}
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0)break;
++l;cout<<"Case "<<l<<":"<<endl;
Adjust();//这里主要是初始化(因为有多组测试数据)
tot=1;
for(int i=1;i<=m;i++)
{
int x,y;cin>>x>>y;
add(x,y);add(y,x);//运用邻接表的形式进行存储;
}
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i,0);
//这个dfn数组主要是计入时间戳;那dfn也就是标明当前这个数有没有做过
for(int i=1;i<=n;i++)
if(!c[i]){
++dcc;dfs(i);
}
tc=1;for(int i=2;i<=tot;i++)
{
int x=ver[i^1],y=ver[i];//这里的i^1指i的领边;
if(c[x]==c[y])continue;
add_c(c[x],c[y]);
}tc/=2;
cin>>q;
for(int i=1;i<=q;i++)
{
int x,y;
cin>>x>>y;
if(c[x]==c[y]){
cout<<tc<<endl;continue;
}
else
{
tc-=lca(x,y);
}cout<<tc<<endl;
}cout<<endl;
}
}
blablabla
我第一次做,做的不好请见谅
挺好的
谢谢