HDU4912

#include<iostream>
#include<cstring>
#include<queue>//注意bfs,a了,但原理不明,模版未當 
#include<algorithm> //hdu4912
#define N 100010
using namespace std;//我還沒定義、。。。 
struct Edge
{
	int from,to,nex;
}edge[2*N];
struct node
{
	int l,r;
	int lca;
}q[N];
int head[N],edgenum,dis[N],fa[N][20],dep[N],vis[N];
int n,m,tim; 




bool cmp(node a,node b)
{
	return dep[a.lca]>dep[b.lca];
} 

void add(int u,int v)
{
	Edge E={u,v,head[u]};
	edge[edgenum]=E;
	head[u]=edgenum++; 
}

void bfs(int root)//用bfs 我理解,但賦值部分不清楚 ,因爲要一層一層找下去所以要用LCA 
{
	queue <int> q;
	dep[root]=0;dis[root]=0;fa[root][0]=root;
	q.push(root);
	while(!q.empty())
	{
	  int u=q.front();
	  q.pop();
	  for(int i=1;i<20;i++)
	  fa[u][i]=fa[fa[u][i-1]][i-1];
	  for(int i=head[u];~i;i=edge[i].nex)
	  {
	  	int v=edge[i].to;
	  	if(fa[u][0]==v)continue;//逗我,這句什麼意思 
	  	dis[v]=dis[u]+1;dep[v]=dep[u]+1;fa[v][0]=u;
	  	q.push(v);
	  } 
	}
}


int LCA(int x,int y)
{
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=0;i<20;i++)  if((dep[x]-dep[y])&(1<<i))x=fa[x][i];
	if(x==y)return x;
	for(int i=19;i>=0;i--)
	if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];	//這年頭很盛行用“逗號” 
	return fa[x][0];
}

void init()
{
	memset(head,-1,sizeof(head));edgenum=0;
} 

int main()//神奇的LCA 
{
		memset(vis,0,sizeof(vis));
		tim=1;	
		int u,v;
		while(~scanf("%d %d",&n,&m))
	{
	int ans=0;
	init();
	tim++;
		for(int i=1;i<n;i++)
		{
		cin>>u>>v;
		add(u,v);
		add(v,u);
		}
		bfs(1);
		for(int i=1;i<=m;i++)
		{
			cin>>q[i].l>>q[i].r;
			q[i].lca=LCA(q[i].l,q[i].r);
		} 
		sort(q+1,q+m+1,cmp);
		
		//主函數也太有個性了吧
		for(int i=1;i<=m;i++)
		{
			int lca=q[i].lca;
			u=q[i].l;v=q[i].r;
			if(vis[lca]==tim)continue;//訪問過 
			bool ok=true; 
			if(lca==u)
			{
				while(v!=lca)
				{
					if(vis[v]==tim)
					{
						ok=false;break;
					}
					v=fa[v][0];//不斷找她的祖先,有沒有被用過的 	
				}
				if(ok)
				{
					ans++;v=q[i].r;//這句別忘呀!! 
					while(v!=lca)
					{
					
					vis[v]=tim;
					v=fa[v][0];
				    }
				vis[lca]=tim;	
				}
				
			}
		
			else if(lca==v)
			{
				while(u!=lca)
				{
					if(vis[u]==tim)
					{
						ok=false;break;
					}
					u=fa[u][0];//不斷找她的祖先,有沒有被用過的 	
				}
				if(ok)
				{
					ans++;u=q[i].l;//這句別忘呀!! 
					while(u!=lca)
					{
						vis[u]=tim;u=fa[u][0];
					}
					vis[lca]=tim;
				}	
			}
			else
			{
				while(v!=lca)
				{
					if(vis[v]==tim){ok=false;break;}
					v=fa[v][0];
				} 
				if(ok)
			    	while(u!=lca)
					{
						if(vis[u]==tim){ok=false;break;}
						u=fa[u][0];
					}
				if(ok)
				{
					ans++;
					u=q[i].l;v=q[i].r;
				while(v!=lca)
				{
						vis[v]=tim;
						v=fa[v][0];
					}
					while(u!=lca)
					{
						vis[u]=tim;
						u=fa[u][0];
					}
					vis[lca]=tim;
				}
				
			}
			
			
			
		}
		cout<<ans<<endl; 
	} 
	return 0;
} 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章