hdu 2460 poj 3694 (双联通+LCA)

在给出的两个点上加一条边,求剩下桥的数量,,不会LCA在线,就用了最普通的,先Tarjan双联通缩点,然后将缩完的图建成一棵树,树的所有边就是桥了,如果在任意两点间加一条边的话,那么从两点到最近公共祖先的所有边都不是桥了。。。。。。






 

#pragma comment(linker, "/STACK:10240000000000,10240000000000")  

#include<stdio.h>

#include<stack>

#include<string.h>

#define N 100010

using namespace std;

int belong[N],low[N],dfs[N],head[N],num,n,idx,ans,nume,vis[N];

struct edge

{

	int st,ed,next;

}E[N*4],e[N*4];

void addedge(int x,int y)

{

	E[num].st=x;

	E[num].ed=y;

	E[num].next=head[x];

	head[x]=num++;

}

void Addedge(int x,int y)

{

	e[nume].st=x;

	e[nume].ed=y;

	e[nume].next=head[x];

	head[x]=nume++;

}

stack<int>Q;

void Tarjan(int u,int father)

{

	int i,v,flag=0;

	low[u]=dfs[u]=idx++;

	Q.push(u);

	for(i=head[u];i!=-1;i=E[i].next)

	{

		v=E[i].ed;

		if(dfs[v]==-1)

		{

			Tarjan(v,u);

			low[u]=low[u]>low[v]?low[v]:low[u];

		}

		else if(v==father)

		{

			if(flag)

				low[u]=low[u]>dfs[v]?dfs[v]:low[u];

			flag++;

		}

		else low[u]=low[u]>dfs[v]?dfs[v]:low[u];

	}

	if(low[u]==dfs[u])

	{

		do

		{

			v=Q.top();

			Q.pop();

			belong[v]=ans;

		}while(v!=u);

		ans++;

	}

}

void dfs1(int u)

{

	vis[u]=1;

	int i,v;

	for(i=head[u];i!=-1;i=e[i].next)

	{

		v=e[i].ed;

		if(vis[v]==1)continue;

		dfs[v]=dfs[u]+1;

		low[v]=u;

		  dfs1(v);

	 }

}

void Lca(int x,int y)

{

	int i;

	if(dfs[x]<dfs[y])

	{i=x;x=y;y=i;}

	while(dfs[x]>dfs[y])

	{

		if(vis[x]==0)

		{

			vis[x]=1;

			ans--;

		}

		x=low[x];

	}

	while(x!=y)

	{

		if(vis[x]==0)

		{

			vis[x]=1;

			ans--;

		}

		if(vis[y]==0)

		{

			vis[y]=1;

			ans--;

		}

		x=low[x];y=low[y];

	}

}

int main()

{

	int i,k,x,y,m,op=1;

	while(scanf("%d%d",&n,&m),n||m)

	{

		memset(head,-1,sizeof(head));

		num=0;

		for(i=0;i<m;i++)

		{

			scanf("%d%d",&x,&y);

			addedge(x,y);

			addedge(y,x);

		}

		memset(dfs,-1,sizeof(dfs));

		idx=ans=0;

		 Tarjan(1,-1);

		 memset(head,-1,sizeof(head));

		 nume=0;

		 for(i=0;i<num;i++)

		 {

			 x=belong[E[i].st];

			 y=belong[E[i].ed];

			 if(x==y)continue;

			 Addedge(x,y);

			 Addedge(y,x);

		 }

		 memset(vis,0,sizeof(vis));

		 dfs[0]=0;

		 low[0]=0;

		 dfs1(0);

		 memset(vis,0,sizeof(vis));

		 printf("Case %d:\n",op++);

		 scanf("%d",&k);		 

		 ans--;

		 while(k--)

		 {

            scanf("%d%d",&x,&y);

				Lca(belong[x],belong[y]);

			printf("%d\n",ans);



		 }

		 printf("\n");

	}

	return 0;

}


 

 

你可能感兴趣的:(poj)