• 【Tarjan,LCA】【3-21个人赛】【problemD】


    Problem D

    Time Limit : 6000/3000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
    Total Submission(s) : 249   Accepted Submission(s) : 32

    Font: Times New Roman | Verdana | Georgia

    Font Size:  

    Problem Description

    WKC有一个收集灯泡的习惯,他把灯泡的阴极都共地,阳极连成一颗树,这样的话,他只要在任意一个灯泡的阳极加上合适的电压,所有灯泡都能亮起来。不幸的是,有一对灯泡之间的阳极连线断掉了,这样的话,这颗灯泡树就还有一部分能亮,一部分不能亮了。WKC想知道如果他在任意一个灯泡的阳极上加电压,这一对灯泡的哪一个会亮?

    Input

    首先是一个正整数T(1<=T<=10)表示测试数据的组数。
    对于每一组测试数据:
    第一行是一个整数n,q(3<=n,q<=100000),n表示灯泡总数,q表示查询个数。
    接下来的n-1行,每行2个整数x,y(1<=x,y<=n),表示灯泡x和灯泡y的阳极相连。(数据保证合法,是一棵树)
    接下来的q行,每行3个整数,a,b,c(1<=a,b,c<=n,数据保证合法,灯泡a和灯泡b之间有边且a不等于b)表示灯泡a和灯泡b之间阳极连线断开的话,在c的阳极加一个电压。

    Output

    每个查询之间相互独立,对于每个查询输出a和b哪一个会亮,输出a或者b即可。

    Sample Input

    1
    3 1
    1 2
    2 3
    1 2 3
    

    Sample Output

    2
    


    算出 a到c距离,b到c距离 ,算距离用LCA

    LCA可以考虑离线的Tarjan算法


    Tarjan算法介绍参考这个

    http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html


    1.注意反向边可以通过 s^1 得到

    2.少用#define maxn 1000+5 具体看置顶


    代码如下“:

    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    #define maxn 100010
    using namespace std;
    int n,q;
    struct Edge{int to,ans,next;
               void GET(int a,int b,int c){to=a,ans=b,next=c;}
               };
    struct Node{int first,deep;};
    Edge E[maxn*6],EE[maxn*6];
    Node Tree[maxn],Q[maxn];
    int _E=0,_EE=0;
    int a[maxn],b[maxn],c[maxn],visit[maxn],father[maxn];
    void init()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    void CLEAR()
    {
       for(int i=1;i<=n;i++)
       {
           Tree[i].first=-1;
              Q[i].first=-1;
        }
        memset(visit,0,sizeof(visit));
        _E=0;_EE=0;
        for(int i=1;i<=100001;i++)
        father[i]=i;
    }
    void Link(int u,int v)
    {
        E[_E].GET(v,0,Tree[u].first);Tree[u].first=_E++;
        E[_E].GET(u,0,Tree[v].first);Tree[v].first=_E++;
    }
    void Link2(int u,int v)
    {
        EE[_EE].GET(v,0,Q[u].first);Q[u].first=_EE++;
        EE[_EE].GET(u,0,Q[v].first);Q[v].first=_EE++;
    }
    int find(int x)
    {
       int r=x;
       while(father[r]!=r)
       {
           r=father[r];
       }
        int i=x;
        while(i!=r)
        {
            int j=father[i];
            father[i]=r;
            i=j;
        }
        return father[x];
    }
    void input()
    {
        int x,y;
        cin>>n>>q;
        CLEAR();
        for(int i=1;i<=n-1;i++)
        {
            scanf("%d%d",&x,&y);
            Link(x,y);
        }
        for(int i=1;i<=q;i++)
        {
            scanf("%d%d%d",&a[i],&b[i],&c[i]);
            Link2(a[i],c[i]);
            Link2(b[i],c[i]);
        }
    }
    void Tarjan(int u,int deep)
    {
        visit[u]=1;
        Tree[u].deep=deep;
        for(int p=Q[u].first;p!=-1;p=EE[p].next)
            if(visit[EE[p].to]==1)
                EE[p^1].ans=EE[p].ans=find(EE[p].to);
    
        int t=0;
        for(int p=Tree[u].first;p!=-1;p=E[p].next)
        {
            if(visit[E[p].to]==0)
        {
            Tarjan(E[p].to,deep+1);
            father[E[p].to]=u;
        }
        }
    }
    void solve()
    {
        Tarjan(1,1);
        int AA=0,BB=0,A=0,B=0;;
        for(int i=1;i<=q;i++)
        {
            for(int p=Q[c[i]].first;p!=-1;p=EE[p].next)
            {
                if(EE[p].to==a[i]) A=EE[p].ans;
                if(EE[p].to==b[i]) B=EE[p].ans;
            }
            AA=Tree[a[i]].deep+Tree[c[i]].deep-2*Tree[A].deep;
            BB=Tree[b[i]].deep+Tree[c[i]].deep-2*Tree[B].deep;
            if(AA<BB) printf("%d
    ",a[i]);
            else printf("%d
    ",b[i]);
        }
    }
    int main()
    {
      //  init();
    	int T;
    	cin>>T;
    	while(T--)
        {
            input();
            solve();
        }
    }
    



  • 相关阅读:
    Eclipse怎么汉化
    eclipse的 project explore找不到了, 怎么把复制来的包放在project explore
    三 地图的绘制
    二 CheatEngine怎么提取地图数据
    一. 透明坦克跑起来
    第七章 继承与派生
    Quoit Design HDU
    C++学习_从C到C++
    C++学习_一道程序填空题重拾C++
    网络爬虫_BeautifulSoup库入门
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480406.html
Copyright © 2020-2023  润新知