• WJC上学记


    WJC上学记
    题目描述:
    WJC为了追求YHY,决定考上树人,但是,愚蠢的他没有足够好的成绩,只能靠自己的亲戚来帮忙。但是由于他足够愚蠢,连自己的亲戚都不认识,仁慈而被树人优录的Geek_du决定帮助他。WJC找了N(0<N<50000)个人,分别和他们进行聊天,聊了E次(0<E<30000)。请帮助WJC找到一些人和他自己的最近公共祖先。

    输入说明:
    输入第一行包含两个整数,N和E。分别表示N个人和E次聊天。
    以下E行每一行包含两个整数,A,B表示A是B的父辈。
    再下面一行包含一个整数M,表明M次查询。
    下面M行每行包含两个整数,P,Q,询问P和Q的最近公共祖先。

    输出说明:
    对于每个查询,给出他们的最近公共祖先。

    样例输入:
    4 3
    1 2
    2 3
    2 4
    1
    3 4

    样例输出:
    2

    数据范围:
    100%:0<N<5000,0<E<30000

    LCA最近公共祖先模板题

    /* ***********************************************
    Author        :buaaasd
    Created Time  :2016/1/23 19:48:00
    File Name     :1.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 100000+10
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    bool cmp(int a,int b){
        return a>b;
    }
    int fa[maxn],n,m,pre[maxn],l;
    int qpre[maxn];
    int ans[maxn*10];
    struct node{
        int v,next;
    }edge[maxn+10];
    struct Node{
        int qv,qnext,id;
    }qedge[maxn*10];
    
    void add(int u,int v){
        edge[l].v=v;
        edge[l].next=pre[u];
        pre[u]=l++;
    }
    void qadd(int u,int v,int id){
        qedge[l].qv=v;
        qedge[l].id=id;
        qedge[l].qnext=qpre[u];
        qpre[u]=l++;
    }
    int findfa(int x){
        if(x==fa[x])return x;
        else return fa[x]=findfa(fa[x]);
    }
    void Union(int x,int y){
        x=findfa(x);
        y=findfa(y);
        fa[y]=x;
    }
    void dfs(int u){
        int v;
        fa[u]=u;
        for(int i=pre[u];i+1;i=edge[i].next){
            v=edge[i].v;
            if(fa[v]==-1){
                dfs(v);
                Union(u,v);
            }
        }
        /*
        for(v=1;v<=n;v++){
            if(fa[v]!=-1){
                lca[u][v]=lca[v][u]=findfa(v);
            }
        }*/
        for(int i=qpre[u];i+1;i=qedge[i].qnext){
            v=qedge[i].qv;
            if(fa[v]!=-1){
                int id=qedge[i].id;
                ans[id]=findfa(v);
            }
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        //freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int x,y;
        while(cin>>n>>m){
            l=0;
            memset(fa,-1,sizeof fa);
            memset(pre,-1,sizeof pre);
            memset(qpre,-1,sizeof qpre);
            for(int i=1;i<=m;i++){
                cin>>x>>y;
                add(x,y);
            }
            l=0;
            int k;
            cin>>k;
            for(int i=1;i<=k;i++){
                scanf("%d%d",&x,&y);
                qadd(x,y,i);
                qadd(y,x,i);
            }
            dfs(1);
            for(int i=1;i<=k;i++){
                printf("%d
    ",ans[i]);
            }
    
        }
        return 0;
    }

    借鉴了网上的许多代码,最后总结的模板。

    这个博主写的最清晰。https://comzyh.com/blog/archives/492/ 而且有图真是极好的。

     链式前向星pre[u]代表以u为起点的第一条边的位置。edge[l].v存储边的终点。edge[l].next存储下一条边的位置。

  • 相关阅读:
    [转] STM32 FSMC学习笔记
    【转】嵌入式系统 Boot Loader 技术内幕
    mini2440 使用 JLink V8 直接烧写 Nor flash
    S3C6410移植uboot(一)
    2440的RTC时钟
    关闭2440 屏幕背光
    基于十级流水线的开立方根算法
    Visual Studio 2008配置SystemC开发环境
    Linux C 中字符串化操作符#
    linux 中 timeval结构体
  • 原文地址:https://www.cnblogs.com/pk28/p/5167516.html
Copyright © 2020-2023  润新知