codeforces 178B
题意:给一个n个点的无向图,m条双向边,保证没有重边和自环,图连通,有q个询问,给两个点,S和T,问从S到T有多少条割边。
思路:看到这题第一反应就是求双连通分量,然后缩点,因为在同一个双连通分量内肯定没有割边,然后缩点后原图就变成了一棵树,因为保证原图连通,所以得到的也只有一颗树,树中的边即为原图中的割边,于是问题就转化成求树中两点的距离了,用LCA即可解决。先贴一个代码。
[cpp]
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#define maxn 100010
using namespace std;
struct edge
{
int to;
int next;
int num;
}e[3][maxn<<2];
int box[3][maxn],cnt[3];
void init()
{
memset(box,-1,sizeof(box));
memset(cnt,0,sizeof(cnt));
}
void add(int from,int to,int num,int t)
{
e[t][cnt[t]].to=to;
e[t][cnt[t]].num=num;
e[t][cnt[t]].next=box[t][from];
box[t][from]=cnt[t]++;
}
int pre[maxn];
int low[maxn];
int bridge[maxn];
int bcnt=0;
int cnt0;
void bridge_search(int now,int fa)
{
int t;
int v,w;
low[now]=pre[now]=++cnt0;
for(t=box[0][now];t+1;t=e[0][t].next)
{
v=e[0][t].to;
if(v==fa)
continue;
if(!pre[v])
{
bridge_search(v,now);
if(low[v]<low[now])
low[now]=low[v];
if(low[v]>pre[now])
{
bridge[e[0][t].num]=1;
}
}
else
{
if(low[now]>pre[v])
low[now]=pre[v];
}
}
}
int Bridge(int n)
{
int i;
cnt0=0;
memset(pre,0,sizeof(pre));
memset(low,0,sizeof(low));
memset(bridge,0,sizeof(bridge));
bcnt=0;
for(i=1;i<=n;i++)
{
if(!pre[i])
{
bridge_search(i,0);
}
}
return bcnt;
}
int vis[maxn];
int dist[maxn];
void Dfs(int now,int num)
{
low[now]=num;
vis[now]=1;
int t,v,nn;
for(t=box[0][now];t+1;t=e[0][t].next)
{
v=e[0][t].to,nn=e[0][t].num;
if(bridge[nn])
continue;
if(!vis[v])
{
Dfs(v,num);
}
}
}
void solve(int n)//Ëõµã
{
int i,sum=0;
memset(low,0,sizeof(low));
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
{
if(!low[i])
Dfs(i,++sum);
}
for(i=1;i<=n;i++)
{
int t,v;
for(t=box[0][i];t+1;t=e[0][t].next)
{
v=e[0][t].to;
if(low[i]!=low[v])
{
add(low[i],low[v],0,1);
add(low[v],low[i],0,1);
}
}
}
}
void dfs(int now,int deep)
{
dist[now]=deep;
vis[now]=1;
int t,v;
for(t=box[1][now];t+1;t=e[1][t].next)
{
v=e[1][t].to;
if(!vis[v])
{
dfs(v,deep+1);
}
}
}
int f[maxn];
void finit(int n)
{
int i;
for(i=0;i<=n;i++)
f[i]=i;
}
int find(int x)
{
if(x==f[x])
return x;
return f[x]=find(f[x]);
}
int ans[maxn];
void lca(int now)
{
f[now]=now;
vis[now]=1;
int t,v,x;
for(t=box[1][now];t+1;t=e[1][t].next)
{
v=e[1][t].to;
if(!vis[v])
{
lca(v);
补充:软件开发 , C++ ,