zoukankan      html  css  js  c++  java
  • 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:
    ",op++);
    		 scanf("%d",&k);		 
    		 ans--;
    		 while(k--)
    		 {
                scanf("%d%d",&x,&y);
    				Lca(belong[x],belong[y]);
    			printf("%d
    ",ans);
    
    		 }
    		 printf("
    ");
    	}
    	return 0;
    }


  • 相关阅读:
    石墨烯
    spring 安装
    orm 对象关系映射
    刷机问题
    环境必备
    spring 例子
    刷系统——黑屏问题
    android 文件下载
    c# 事件处理
    回忆测试广告理论
  • 原文地址:https://www.cnblogs.com/aukle/p/3233774.html
Copyright © 2011-2022 走看看