zoukankan      html  css  js  c++  java
  • 【POJ1986】Distance Queries-LCA算法

    题目:POJ1986

    做法:一道LCA算法的模板题,比较简单,就不多说了。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int n,m,a,b,c,d,tot,first[100010],firstq[40010],fa[100010];
    int lca[40010],f[100010],root[100010];
    long long dis[100010];
    char ch;
    bool vis[100010],visr[100010];
    struct {int v,d,next;} e[200010];
    struct {int v,next;} q[80010];
    
    void insert(int x,int y,int d)
    {
      e[++tot].v=y;
      e[tot].d=d;
      e[tot].next=first[x];
      first[x]=tot;
    }
    
    void insertq(int x,int y,int d)
    {
      q[++tot].v=y;
      q[tot].next=firstq[x];
      firstq[x]=tot;
    }
    
    int find(int x)
    {
      int r=x,i=x,j;
      while(f[r]!=r) r=f[r];
      while(i!=r)
      {
        j=f[i];
    	f[i]=r;
    	i=j;
      }
      return r;
    }
    
    void merge(int a,int b)
    {
      int x=find(a),y=find(b);
      f[x]=y;
    }
    
    int findrt(int x)
    {
      int r=x,i=x,j;
      while(root[r]!=r) r=root[r];
      while(i!=r)
      {
        j=root[i];
    	root[i]=r;
    	i=j;
      }
      return r;
    }
    
    void mergert(int a,int b)
    {
      int x=findrt(a),y=findrt(b);
      root[x]=y;
    }
    
    void tarjan(int v)
    {
      f[v]=v;
      for(int i=first[v];i>0;i=e[i].next)
        if (e[i].v!=fa[v])
    	{
    	  fa[e[i].v]=v;
    	  dis[e[i].v]=dis[v]+e[i].d;
    	  tarjan(e[i].v);
    	}
      for(int i=firstq[v];i>0;i=q[i].next)
        if (vis[q[i].v]||v==q[i].v) lca[i/2+(i%2)]=find(q[i].v);
      vis[v]=1;
      merge(v,fa[v]);
    }
    
    int main()
    {
      scanf("%d%d",&n,&m);
      dis[1]=fa[1]=tot=0;
      for(int i=1;i<=n;i++) root[i]=i;
      for(int i=1;i<=m;i++)
      {
    	scanf("%d%d%d%c",&a,&b,&d,&ch);
    	while(ch<'A'||ch>'Z') scanf("%c",&ch);
    	insert(a,b,d);insert(b,a,d);
    	int fa=findrt(a),fb=findrt(b);
    	if (fa!=fb) mergert(a,b);
      }
      tot=0;
      scanf("%d",&c);
      for(int i=1;i<=c;i++)
      {
    	scanf("%d%d",&a,&b);
    	insertq(a,b,i);insertq(b,a,i);
      }
      for(int i=1;i<=n;i++) f[i]=i;
      for(int i=1;i<=n;i++)
    	if (!visr[findrt(i)]) {tarjan(findrt(i));visr[findrt(i)]=1;}
      for(int i=1;i<=c;i++)
      {
    	a=q[2*i].v,b=q[2*(i-1)+1].v;
    	if (findrt(a)!=findrt(b)) printf("-1
    ");
    	else printf("%lld
    ",dis[a]+dis[b]-2*dis[lca[i]]);
      }
      
      return 0;
    }


  • 相关阅读:
    Web开发快速上手
    前端概述
    Python语言进阶
    图像和办公文档处理
    网络编程
    进程和线程
    正则表达式
    面向对象进阶
    面向对象
    js 获取指定时间上月26 ,
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793969.html
Copyright © 2011-2022 走看看