程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu 2874 (LCA)

hdu 2874 (LCA)

編輯:C++入門知識

虛擬賽的時候,一看是求任意兩點的最短路,不管怎麼優化都超時,最近做一些樹的題目,這是求任意兩點到最近公共祖先的距離,先用並差集判斷是否聯通,聯通就求最近公共祖先,先把圖建成一棵棵樹,

 

 

 

 


 

#include<string.h>
#include<stdio.h>
#define N 10010
int father[N],dfs[N],n,vis[N],head[N],num,f[N],ans,dis[N];
struct edge
{
	int st,ed,next,w;
}E[N*2];
void addedge(int x,int y,int w)
{
	E[num].st=x;
	E[num].ed=y;
	E[num].w=w;
	E[num].next=head[x];
	head[x]=num++;
}
int find(int a)
{
	if(f[a]!=a)
		f[a]=find(f[a]);
	return f[a];
}
void dfs1(int u)
{
	int i,v;
	vis[u]=1;
	for(i=head[u];i!=-1;i=E[i].next)
	{
		v=E[i].ed;
		if(vis[v]==1)continue;
		father[v]=u;
		dfs[v]=dfs[u]+1;
		dis[v]=E[i].w;
		dfs1(v);
	}
	if(ans<dfs[u])
		ans=dfs[u];
}
int LCA(int x,int y)
{
	int sum=0;
	while(dfs[x]>dfs[y])
	{
		sum+=dis[x];
		x=father[x];
	}
	while(dfs[y]>dfs[x])
	{
		sum+=dis[y];
		y=father[y];
	}
	while(x!=y)
	{
		sum+=(dis[x]+dis[y]);
		x=father[x];
		y=father[y];
	}
	return sum;
}
int main()
{
	int i,j,k,x,y,m,ans,w;
	while(scanf("%d%d%d",&n,&m,&k)!=-1)
	{
		memset(head,-1,sizeof(head));
		num=0;
		for(i=1;i<=n;i++)
			f[i]=i;
		for(i=0;i<m;i++)
		{
			scanf("%d%d%d",&x,&y,&w);
			addedge(x,y,w);
			addedge(y,x,w);
			x=find(x);
			y=find(y);
			if(x!=y)
				f[x]=find(y);
		}
		memset(vis,0,sizeof(vis));
		ans=1;
		for(i=1;i<=n;i++)
		{
			if(vis[i]==0)
			{				
				dis[i]=0;
				dfs[i]=ans;
				father[i]=i;
				dfs1(i);
				ans++;
			}
		}
		while(k--)
		{
			scanf("%d%d",&x,&y);
			if(find(x)!=find(y))
			{printf("Not connected\n");continue;}
			j=LCA(x,y);
			printf("%d\n",j);
		}
	}
	return 0;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved