• HDU ACM 2586 How far away ?LCA->并查集+Tarjan(离线)算法


    题意:一个村子有n个房子,他们用n-1条路连接起来,每两个房子之间的距离为w。有m次询问,每次询问房子a,b之间的距离是多少。

    分析:近期公共祖先问题,建一棵树,求出每一点i到树根的距离d[i],每次询问a。b之间的距离=d[a]+d[b]-2*d[LCA(a,b)];LCA(a,b)是a,b的近期公共祖先。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<vector>
    using namespace std;
    
    #define N 50005
    vector<int> map[N],w[N],query[N],num[N];
    int p[N],d[N],res[N];
    bool vis[N];
    int n;
    
    void Init()
    {
    	int i;
    	for(i=1;i<=n;i++)
    	{
    		map[i].clear();
    		w[i].clear();
    		query[i].clear();
    		num[i].clear();
    		p[i]=i;
    		d[i]=0;
    		vis[i]=false;
    	}
    }
    
    int Find(int x)
    {
    	if(p[x]!=x)
    		p[x]=Find(p[x]);
    	return p[x];
    }
    
    void Union(int x,int y)
    {
    	x=Find(x);
    	y=Find(y);
    	if(x!=y)
    		p[y]=x;
    }
    
    void Tarjan(int cur,int v)
    {
    	int size,i,tmp;
    
    	vis[cur]=true;
    	d[cur]=v;
    	size=map[cur].size();
    	for(i=0;i<size;i++)
    	{
    		tmp=map[cur][i];
    		if(vis[tmp]) continue;
    		Tarjan(tmp,v+w[cur][i]);
    		Union(cur,tmp);
    	}
    	size=query[cur].size();
    	for(i=0;i<size;i++)
    	{
    		tmp=query[cur][i];
    		if(!vis[tmp])continue;
    		res[num[cur][i]]=d[cur]+d[tmp]-2*d[Find(tmp)];
    	}
    }
    
    int main()
    {
    	int T,q,a,b,c,i;
    
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d",&n,&q);
    		Init();
    		for(i=1;i<n;i++)
    		{
    			scanf("%d%d%d",&a,&b,&c);
    			map[a].push_back(b);
    			w[a].push_back(c);
    			map[b].push_back(a);
    			w[b].push_back(c);
    		}
    		for(i=0;i<q;i++)
    		{
    			scanf("%d%d",&a,&b);
    			query[a].push_back(b);
    			query[b].push_back(a);
    			num[a].push_back(i);
    			num[b].push_back(i);
    		}
    		Tarjan(1,0);
    		for(i=0;i<q;i++)
    			printf("%d
    ",res[i]);
    	}
    	return 0;
    }
    


  • 相关阅读:
    洛谷 P1653 猴子 解题报告
    洛谷 P2024 [NOI2001]食物链 解题报告
    洛谷 P1966 火柴排队 解题报告
    洛谷 P1311 选择客栈 解题报告
    洛谷 P3959 宝藏 解题报告
    二进制枚举子集技巧
    洛谷 P1841 [JSOI2007]重要的城市 解题报告
    洛谷 P2324 [SCOI2005]骑士精神 解题报告
    vector-size
    ubuntu 更换软件源
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5066128.html
Copyright © 2020-2023  润新知