http://acm.hdu.edu.cn/showproblem.php?pid=2460
http://poj.org/problem?id=3694
/**
hdu2460&&poj3694 缩点+lca变形
题目大意:给定一个图,然后依次加一些边,求每加入一条边后现有的图中含有多少桥
解题思路:先把所有的强连通分量进行缩点,然后现有桥的个数为点数减一,而后每增加一条边u->v那么u,v到它们lca所在的环之间的桥都要减去。
先dfs将所有的桥标记(采用标记点的方式标记桥),然后每次加边来一次向根节点查找就好了
*/
#pragma comment(linker, "/STACK:10240000000000,10240000000000")/// 申请空间hdu需要
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=200005;
int head[maxn],ip;
int m,n,bridge,ans;
int low[maxn],dfn[maxn],dex,cnt,st[maxn],inst[maxn],belong[maxn],top;
void init()
{
memset(head,-1,sizeof(head));
ip=0;
}
struct note
{
int v,cut,next;
}edge[maxn*2];
void addedge(int u,int v)
{
edge[ip].v=v,edge[ip].cut=0,edge[ip].next=head[u],head[u]=ip++;
}
void tarjan(int u,int pre)
{
dfn[u]=low[u]=++dex;
st[top++]=u;
inst[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v==pre)continue;
if(dfn[v]==0)
{
tarjan(v,u);
if(low[u]>low[v])low[u]=low[v];
if(low[v]>low[u])
{
bridge++;
edge[i].cut=1;
edge[i^1].cut=1;
}
}
else if(inst[v]&&low[u]>dfn[v])
{
low[u]=dfn[v];
}
}
if(dfn[u]==low[u])
{
int j;
cnt++;
do
{
j=st[--top];
inst[j]=0;
belong[j]=cnt;
}
while(j!=u);
}
}
vector vec[maxn];
int father[maxn];
int dep[maxn];
int a[maxn];
void bfs(int root)
{
memset(dep,-1,sizeof(dep));
dep[root]=0;
a[root]=0;
father[root]=-1;
queueq;
q.push(root);
while(!q.empty())
{
int tmp=q.front();
q.pop();
for(int i=0;idep[v])swap(u,v);
while(dep[u]