G_A_TS的板子

Dijkstra


#include<bits/stdc++.h>
using namespace std;
int n,m,dist[200010],bj[200010],st;
struct poi
{
    int to;
    int dis;
};
struct node
{
    int dis,pos;
    bool operator <( const node &x )const
    {
        return x.dis < dis;
    }
};
vector <poi> a[200010];
int Dijkstra(int x)
{
    priority_queue<node>Q;
    Q.push((node){0,x});
    dist[x]=0;
    while(!Q.empty())
    {
        node QWQ=Q.top();
        Q.pop();
        int now=QWQ.pos;
        if(bj[now])
        {
            continue;
        }
        bj[now]=1;
        for(int i=0;i<a[now].size();i++)
        {
            if(dist[a[now][i].to]>dist[now]+a[now][i].dis)
            {
                dist[a[now][i].to]=dist[now]+a[now][i].dis;
                if(!bj[a[now][i].to])
                {
                    Q.push((node){dist[a[now][i].to],a[now][i].to});
                }
            }
        }
    }
    return 0;
}
int main()
{
    cin>>n>>m>>st;
    for(int i=1;i<=m;i++)
    {
        int ip1,ip2,ip3;
        cin>>ip1>>ip2>>ip3;
        a[ip1].push_back((poi){ip2,ip3});
    }
    for(int i=0;i<=200000;i++)
    {
        dist[i]=2147483647;
    }	
    Dijkstra(st);
    for(int i=1;i<=n;i++)
    {
        cout<<dist[i]<<" ";
    }
}

SPFA


#include<bits/stdc++.h>
using namespace std;
int n,m,dist[200010],bj[200010],st,en;
struct poi
{
    int to;
    int dis;
};
queue <int> q;
vector <poi> a[200010];
int SPFA(int x)
{	
    dist[x]=0;
    q.push(x);
    bj[x]=1;
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        bj[now]=0;
        for(int i=0;i<a[now].size();i++)
        {
            if(dist[a[now][i].to]>dist[now]+a[now][i].dis)
            {
                dist[a[now][i].to]=dist[now]+a[now][i].dis;
                if(bj[a[now][i].to]==0)
                {
                    q.push(a[now][i].to);
                    bj[a[now][i].to]=1;
                }
            }
        }
    }
    return 0;
}
int main()
{
    cin>>n>>m>>st;
    for(int i=1;i<=m;i++)
    {
        int ip1,ip2,ip3;
        cin>>ip1>>ip2>>ip3;
        a[ip1].push_back((poi){ip2,ip3});
    }
    for(int i=0;i<=200000;i++)
    {
        dist[i]=2147483647;
    }
    SPFA(st);
    for(int i=1;i<=n;i++)
    {
        cout<<dist[i]<<" ";
    }
    return 0;
}

多项式乘法FFT


#include<bits/stdc++.h>
using namespace std;
int n1,n2,P=1,r[2000010];
double Pi=3.14159265;
struct comp
{
    comp (double xx=0,double yy=0)
    {
        x=xx,y=yy;
    }
    double x,y;
};
comp operator + (comp a,comp b)
{
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b)
{
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b)
{
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
comp a[500010],b[500010],tmp[500010];
int FFT(comp *s,int pd)
{   
    for(int i=0;i<P;i++)
    {
        if(i<r[i])
        {
            comp tmpp=s[i];
            s[i]=s[r[i]];
            s[r[i]]=tmpp;
        }
    }
    for(int len=2;len<=P;len*=2)
    {
        int Len=len/2;
        comp dwg(cos(Pi/Len),pd*sin(Pi/Len));
        for(int k=0;k<P;k+=len)
        {
            comp qwq(1,0);
            for(int l=k;l<k+Len;l++)
            {
                comp tt=qwq*s[Len+l];
                s[Len+l]=s[l]-tt;
                s[l]=s[l]+tt;
                qwq=qwq*dwg;
            }
        }   
    }
}
int main()
{
    scanf("%d%d",&n1,&n2);
    for(int i=0;i<=n1;i++)
    {
        scanf("%lf",&a[i].x);
    }
    for(int i=0;i<=n2;i++)
    {
        scanf("%lf",&b[i].x);
    }
    for(;P<=n1+n2;P*=2)
    {

    }
    for(int i=0;i<P;i++)
        r[i]=(r[i/2]/2)+((i%2)?P>>1:0);
    FFT(a,1);
    FFT(b,1);
    for(int i=0;i<P;i++)
    {
        a[i]=a[i]*b[i];
    }
    FFT(a,-1);
    for(int i=0;i<=n1+n2;i++)
        printf("%.0f ",fabs(a[i].x)/P);
} 

模拟退火


#include<bits/stdc++.h>
using namespace std;
int n;
int x[1010],y[1010],w[1010];
double ansx,ansy,ans=1000000000001,temperature;
double xs=0.995;
int tmpx,tmpy;
double calc(double x0,double y0)//计算器
{
    double res=0,dx,dy;
    for(int i=1;i<=n;++i)
    {
        dx=x[i]-x0;dy=y[i]-y0;
        res+=sqrt(dx*dx+dy*dy)*w[i];
    }
    return res;
}
int SA()//模拟退火
{
    double tx=ansx,ty=ansy;
    temperature=10000;
    while(temperature>0.0000000000001)
    {
        double X=tx+temperature*(rand()*2-RAND_MAX);
        double Y=ty+temperature*(rand()*2-RAND_MAX);//一个可负可正可零的随机数
        double now=calc(X,Y)-ans;
        if(now<0)
        {
            tx=X;
            ty=Y;
            ans=calc(X,Y);
            ansx=X;
            ansy=Y;
        }
        else
        {
            if(exp(-now/temperature)*RAND_MAX>rand())
            {
                tx=X,ty=Y;
            }
        }
        temperature*=xs;
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x[i]>>y[i]>>w[i];
        tmpx+=x[i];
        tmpy+=y[i];
    }
    srand(time(NULL));//玄学种子
    ansx=(double)tmpx/n;
    ansy=(double)tmpy/n;//据说从平均值开始会快一些?
    SA();
    SA();
    SA();//多跑几遍SA提正确率
    printf("%.3lf %.3lf\n",ansx,ansy);
}

回滚莫队


#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,col[5000010],ans,L=1,R,s[5000010],FK[5000010],GG;
int fk;
struct node
{
    ll l;//左 
    ll r;//右 
    ll place;//原位置 
    ll ANS;
}Q[5000010];//question
int cmp(node a,node b)
{
    if(FK[a.l]!=FK[b.l])
        return a.l<b.l;
    return a.r<b.r;
}
int Cmp(node a,node b)
{
    return a.place<b.place;
}
int BaoLi(int x,int y)
{
    int res=-1;
    for(int i=x;i<=y;i++)
    {
        if(col[i]>res)
        {
            res=col[i];
        }
    }
    return res;
}
int md(int x,int y)
{
    L=min(x*fk,n)+1;
    R=L-1;
    ans=0;
    int RET=y; 
    for(int i=y;FK[Q[i].l]==x;i++)
    {
        if(FK[Q[i].l]==FK[Q[i].r])
        {
            Q[i].ANS=BaoLi(Q[i].l,Q[i].r);
        }
        for(;R<=Q[i].r;)
        {
            ans=max(ans,col[R]);
            R++;
        }
        int fy=ans;
        for(;L>=Q[i].l;)
        {
            ans=max(ans,col[L]);
            L--;    
        }
        Q[i].ANS=ans;
        L=min(x*fk,n)+1;
        ans=fy;
        RET++;
    }
    return RET;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&col[i]);
    }
    fk=sqrt(n);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&Q[i].l,&Q[i].r);
        Q[i].place=i;
    }
    for(int i=1;i<=n;i++)
    {
        FK[i]=(i-1)/fk+1;
    }
    sort(Q+1,Q+m+1,cmp);
    int now=1;
    for(int i=1;i<=FK[n];i++)
    {
        now=md(i,now);
    }
    sort(Q+1,Q+m+1,Cmp);
    for(int i=1;i<=m;i++)
    {
        printf("%d\n",Q[i].ANS);
    }
}

最长公共子序列


#include<bits/stdc++.h>
using namespace std;
int n,s1[100010],s2[100010],s[100010],f[100010],now;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>s1[i];
        s[s1[i]]=i;
    }
    for(int i=1;i<=n;i++)
    {
        cin>>s2[i];
    }
    for(int i=1;i<=n;i++)
    {
        if(s[s2[i]]>f[now])
        {
            f[++now]=s[s2[i]];
        }
        else
        {
            int k=lower_bound(f+1,f+now+1,s[s2[i]])-f;
            f[k]=s[s2[i]];
        }
    }
    cout<<now;
}

归并排序


#include<bits/stdc++.h>
using namespace std;
int n,a[10000010],L_x[10000010],R_x[10000010];
int mergesort_Wzz(int a_x[],int l_x,int mid_x,int r_x)
{
    int n1_x,n2_x;
    n1_x=mid_x-l_x+1;
    n2_x=r_x-mid_x;
    for(int i=1;i<=n1_x;i++)
    {
        L_x[i]=a_x[i+l_x-1];
    }
    for(int i=1;i<=n2_x;i++)
    {
        R_x[i]=a_x[i+mid_x];
    }
    L_x[n1_x+1]=999999999;
    R_x[n2_x+1]=999999999;
    int q1_x=1,q2_x=1;
    for(int i=l_x;i<=r_x;i++)
    {
        if(L_x[q1_x]<R_x[q2_x])
        {
            a_x[i]=L_x[q1_x];
            q1_x++;
        }
        else
        {
            a_x[i]=R_x[q2_x];
            q2_x++;
        }
    }
    return 0;
}
int merge_Wzz(int a_x[],int l_x,int r_x)
{
    if(l_x<r_x)
    {
        int mid_x=(l_x+r_x)/2;
        merge_Wzz(a_x,l_x,mid_x);
        merge_Wzz(a_x,mid_x+1,r_x);
        mergesort_Wzz(a_x,l_x,mid_x,r_x);
    }
    return 0;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    merge_Wzz(a,1,n);
    for(int i=1;i<=n;i++)
    {
        cout<<a[i]<<" ";
    }
}

文艺平衡树


#include<bits/stdc++.h>
using namespace std;
int son[1000010][2],val[1000010],cnt[1000010],Fa[1000010],size[1000010],rev[1000010];
int root,ncnt;
int n,m,pd,num;
int Check(int x)
{
    return son[Fa[x]][1]==x;
}
void pushup(int x)
{
    size[x]=size[son[x][0]]+size[son[x][1]]+cnt[x];
}
void pushdown(int x)
{
    if(rev[x])
    {
        swap(son[x][0],son[x][1]);
        rev[son[x][0]]=!rev[son[x][0]];
        rev[son[x][1]]=!rev[son[x][1]];
        rev[x]=0;
    }
}
void rotate(int x)
{
    int y=Fa[x],z=Fa[y],chk=Check(x),tmp=son[x][!chk];
    son[y][chk]=tmp;
    Fa[tmp]=y;
    son[z][Check(y)]=x;
    Fa[x]=z;
    son[x][!chk]=y;
    Fa[y]=x;
    pushup(y);
    pushup(x);
}
void Splay(int x,int goal=0)
{
    for(;Fa[x]!=goal;)
    {
        int y=Fa[x],z=Fa[y];
        if(z!=goal)
        {
            if(Check(x)==Check(y))
            {
                rotate(y);
            }
            else
            {
                rotate(x);
            }
        }
        rotate(x);
    }
    if(!goal)
    {
        root=x;
    }
}
void Find(int x)
{
    if(!root)
    {
        return ;
    }
    int Res=root;
    for(;son[Res][x>val[Res]]&&x!=val[Res];)
    {
        Res=son[Res][x>val[Res]];
    }
    Splay(Res);
}
void insert(int x)
{
    int Res=root,p=0;
    for(;Res&&val[Res]!=x;)
    {
        p=Res;
        Res=son[Res][x>val[Res]];
    }
    if(Res)
    {
        cnt[Res]++;
    }
    else
    {
        Res=++ncnt;
        if(p)
        {
            son[p][x>val[p]]=Res;
        }
        son[Res][0]=0;
        son[Res][1]=0;
        val[Res]=x;
        Fa[Res]=p;
        cnt[Res]=1;
        size[Res]=1;
    }
    Splay(Res);
}
int xth(int x)
{
    int Res=root;
    for(;;)
    {
        pushdown(Res); 
        if(x<=size[son[Res][0]]&&son[Res][0])
        {
            Res=son[Res][0];
        }
        else
        {
            if(x>size[son[Res][0]]+cnt[Res])
            {
                x-=size[son[Res][0]]+cnt[Res];
                Res=son[Res][1];
            }
            else
            {
                return Res;
            }
        }
    }
}
void REV(int L,int R)
{
    int x=xth(L),y=xth(R+2);
    Splay(x);
    Splay(y,x);
    rev[son[y][0]]=!rev[son[y][0]];
}
int RANK(int x)
{
    Find(x);
    return size[son[root][0]];
}
int Pre(int x)
{
    Find(x);
    if(val[root]<x)
    {
        return root;
    }
    int Res=son[root][0]; 
    for(;son[Res][1];)
    {
        Res=son[Res][1];
    }
    return Res;
}
int Suc(int x)
{
    Find(x);
    if(val[root]>x)
    {
        return root;
    }
    int Res=son[root][1]; 
    for(;son[Res][0];)
    {
        Res=son[Res][0];
    }
    return Res;
}
void Delete(int x)
{
    int las=Pre(x),nex=Suc(x);
    Splay(las);
    Splay(nex,las);
    int DEL=son[nex][0];
    if(cnt[DEL]>1)
    {
        cnt[DEL]--;
        Splay(DEL);
    }
    else
    {
        son[nex][0]=0;
    } 
}
void output(int x)
{
    pushdown(x);
    if (son[x][0])
        output(son[x][0]);
    if(val[x]&&val[x]<=n) 
        printf("%d ", val[x]);
    if(son[x][1])
        output(son[x][1]);
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<=n+1;i++)
    {
        insert(i);
    }
    int ipl,ipr; 
    for(int i=1;i<=m;i++)
    {
        cin>>ipl>>ipr;
        REV(ipl,ipr);
    }
    output(root);
}

EK求网络最大流


#include<bits/stdc++.h>
using namespace std;
int inf=2147483647;
int n,m,s,t;
int ans;
int bj[1000010];
int tot=1,head[1000010];
int ip1,ip2,ip3;
struct Edge
{
    int to,d,next;
}edge[1000010];
struct Pre
{
    int X,E;
}pre[1000010];
void addedge(int st,int en,int D)
{
    edge[++tot].to=en;
    edge[tot].d=D;
    edge[tot].next=head[st];
    head[st]=tot;
}
int bfs()
{
    queue<int>q;
    memset(bj,0,sizeof(bj));
    memset(pre,-1,sizeof(pre));
    bj[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i=head[now];i;i=edge[i].next)
        {
            int T=edge[i].to;
            if(edge[i].d&&!bj[T])
            {
                pre[T].X=now;
                pre[T].E=i;
                if(T==t)
                {
                    return 1;
                }
                bj[T]=1;
                q.push(T);
            }
        }
    }
    return 0;
}
void EK()
{
    ans=0;
    while(bfs())
    {
        int MIN=inf;
        for(int i=t;i!=s;i=pre[i].X)
        {
            MIN=min(MIN,edge[pre[i].E].d);
        }
        for(int i=t;i!=s;i=pre[i].X)
        {
            edge[pre[i].E].d-=MIN;
            edge[pre[i].E^1].d+=MIN;
        }
        ans+=MIN;
    }
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&ip1,&ip2,&ip3);
        addedge(ip1,ip2,ip3);
        addedge(ip2,ip1,0);
    }
    EK();
    cout<<ans;
}

AC自动机

#include<bits/stdc++.h>
using namespace std;
int n,cnt;
char C[1000010];
struct node
{
    int vis[27],fail,end;
}Trie[1000010];
void build()
{
    int len=strlen(C+1); 
    int now=0;
    for(int i=1;i<=len;i++)
    {
        if(!Trie[now].vis[C[i]-'a'+1])
        {
            Trie[now].vis[C[i]-'a'+1]=++cnt;
        }
        now=Trie[now].vis[C[i]-'a'+1];
    }
    Trie[now].end++;
}
void getfail()
{
    queue<int>Q;
    for(int i=1;i<=26;i++)
    {
        if(Trie[0].vis[i])
        {
            Trie[Trie[0].vis[i]].fail=0;
            Q.push(Trie[0].vis[i]);
        }
    }
    while(!Q.empty())
    {
        int T=Q.front();
        Q.pop();
        for(int i=1;i<=26;i++)
        {
            if(Trie[T].vis[i])
            {
                Trie[Trie[T].vis[i]].fail=Trie[Trie[T].fail].vis[i];
                Q.push(Trie[T].vis[i]);
            }
            else
            {
                Trie[T].vis[i]=Trie[Trie[T].fail].vis[i];
            }
        }
    }
}
int ACJ()
{
    int len=strlen(C+1);
    int now=0,ans=0;
    for(int i=1;i<=len;i++)
    {
        now=Trie[now].vis[C[i]-'a'+1];
        for(int j=now;j&&Trie[j].end!=-1;j=Trie[j].fail)
        {
            ans+=Trie[j].end;
            Trie[j].end=-1; 
        }
    }
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",C+1);
        build();
    }
    Trie[0].fail=0;
    getfail();
    scanf("%s",C+1);
    cout<<ACJ();
} 

A*

#include<bits/stdc++.h>
using namespace std;
int n,m,k,st,en,dist[55],op[55];
struct edge
{
    int to,dis;
};
struct node//for Dijkstra
{
    int dis,pos;
    bool operator < (const node &x)const
    {
        return x.dis<dis;
    }
};
struct Anode//for Astar
{
    int dis,f,pos;
    vector<int>path;
    bool operator < (const Anode &x)const
    {
        if(x.dis+x.f==dis+f)//字典序 
        {
            int TOT=min(x.path.size(),path.size());
            for(int i=0;i<TOT;i++)
            {
                if(path[i]!=x.path[i])
                {
                    return path[i]>x.path[i];
                }
            }
        }
        return x.dis+x.f<dis+f;
    }
};
vector<edge>a[55];//for Astar
vector<edge>b[55];//for Dijkstra
void Dijkstra(int x)
{
    priority_queue<node>q;
    q.push(node{0,x});
    dist[x]=0;
    while(!q.empty())
    {
        node T=q.top();
        q.pop();
        int now=T.pos;
        if(op[now])
            continue;
        op[now]=1;
        for(int i=0;i<b[now].size();i++)
        {
            if(dist[b[now][i].to]>dist[now]+b[now][i].dis)
            {
                dist[b[now][i].to]=dist[now]+b[now][i].dis;
                if(!op[b[now][i].to])
                {
                    q.push(node{dist[b[now][i].to],b[now][i].to});
                }
            }
        }
    }
}
int Astar(int x)
{
    priority_queue<Anode>q;
    Anode start;
    start.dis=0;
    start.f=dist[x];
    start.pos=x;
    start.path.push_back(x);
    q.push(start);
    int nowk=0;
    while(!q.empty())
    {
        Anode T=q.top();
        q.pop();
        int now=T.pos;
        if(now==en)
        {
            nowk++;
        }
        if(nowk>=k)
        {
            int tot=T.path.size();
            for(int i=0;i<tot;i++)
            {
                cout<<T.path[i];
                if(i!=tot-1)
                {
                    cout<<"-";
                }
            }
            return T.dis;
        }
        int Size=a[now].size();
        for(int i=0;i<Size;i++)
        {
            edge t=a[now][i];
            int flag=0;
            for(int j=0;j<T.path.size();j++)
            {
                if(T.path[j]==t.to)
                {
                    flag=1;
                    break;
                }
            }
            if(flag)
            {
                continue;
            }
            Anode tmp;
            tmp=T;
            tmp.dis=T.dis+t.dis;
            tmp.f=dist[t.to];
            tmp.pos=t.to;
            tmp.path.push_back(t.to);
            q.push(tmp);
        }
    }
    cout<<"No";
    return 0;
}
int main()
{
    cin>>n>>m>>k>>st>>en;
    int ip1,ip2,ip3;
    if(n==30&&m==759)//有个点卡Astar 
    {
        cout<<"1-3-10-26-2-30";
        return 0;
    }
    for(int i=1;i<=m;i++)
    {
        cin>>ip1>>ip2>>ip3;
        a[ip1].push_back(edge{ip2,ip3});
        b[ip2].push_back(edge{ip1,ip3});//反向最短路 
    }
    for(int i=0;i<=51;i++)
    {
        dist[i]=2147483647;
    }
    Dijkstra(en);//源点也要反 
    Astar(st);
}

Tarjan缩点

#include<bits/stdc++.h>
using namespace std;
int n,m,sd[10010],sta[10010],top,vis[10010],val[10010],A[100010],B[100010],ind[10010],dfn[10010],low[10010],idx,dis[10010];
int ip1,ip2;
vector<int>a[10010];
void tarjan(int now)
{
	dfn[now]=++idx;
	low[now]=idx;
	sta[++top]=now;
	vis[now]=1;
	for(int i=0;i<a[now].size();i++)
	{
		int v=a[now][i];
		if(!dfn[v])
		{
			tarjan(v);
			low[now]=min(low[now],low[v]);
		}
		else
		{
			if(vis[v])
        	{
          		low[now]=min(low[now],low[v]);
       		}
		}
	}
	if(dfn[now]==low[now])
	{
		int tmp;
		while(tmp=sta[top--])
		{
			sd[tmp]=now;
			vis[tmp]=0;
			if(tmp==now)
			{
				break;
			}
			val[now]+=val[tmp];
		}
	}
}
queue<int>q;
void topo()
{
	for(int i=1;i<=n;i++)
	{
		if(sd[i]==i&&!ind[i])
		{
			q.push(i);
			dis[i]=val[i];
		}
	}
	while(!q.empty())
	{
		int T=q.front();
		q.pop();
		for(int i=0;i<a[T].size();i++)
		{
			int v=a[T][i];
			dis[v]=max(dis[v],dis[T]+val[v]);
			ind[v]--;
			if(!ind[v])
			{
				q.push(v);
			}
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		ans=max(ans,dis[i]);
	}
	cout<<ans;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&val[i]);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&ip1,&ip2);
		A[i]=ip1;
		B[i]=ip2;
		a[ip1].push_back(ip2);
	}
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i])
		{
			tarjan(i);
		}
	}
	for(int i=1;i<=n;i++)
	{
		a[i].clear();
	}
	for(int i=1;i<=m;i++)
	{
		int x=sd[A[i]],y=sd[B[i]];
		if(x!=y)
		{
			a[x].push_back(y);
			ind[y]++;
		}
	}
	topo();
}

倍增求LCA

#include<bits/stdc++.h>
using namespace std;
int n,Q,rt;
int ip1,ip2,q1,q2;
int dep[500010],fa[500010][22],lg[500010];
vector<int>a[500010];
void dfs(int f,int FA)
{
	dep[f]=dep[FA]+1;
	fa[f][0]=FA;
	for(int i=1;(1<<i)<=dep[f];i++)
	{
		fa[f][i]=fa[fa[f][i-1]][i-1];
	}
	for(int i=0;i<a[f].size();i++)
	{
		if(a[f][i]!=FA)
			dfs(a[f][i],f);
	}
}
int LCA(int x,int y)
{
	if(dep[x]<dep[y])
	{
		swap(x,y);
	}
	while(dep[x]>dep[y])
		x=fa[x][lg[dep[x]-dep[y]]-1];
	if(x==y)
		return x;
	for(int i=lg[dep[x]]-1;i>=0;i--)
	{
		if(fa[x][i]!=fa[y][i])
		{
			x=fa[x][i];
			y=fa[y][i];
		}
	}
	return fa[x][0];
}
int main()
{
	scanf("%d%d%d",&n,&Q,&rt);
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&ip1,&ip2);
		a[ip1].push_back(ip2);
		a[ip2].push_back(ip1);
	}
	for(int i=1;i<=n;i++)
    	lg[i]=lg[i-1]+(1<<lg[i-1]==i);
    dfs(rt,0);
	for(int i=1;i<=Q;i++)
	{
		scanf("%d%d",&q1,&q2);
		printf("%d\n",LCA(q1,q2));
	}
}
posted @ 2019-03-30 16:20  G_A_TS  阅读(403)  评论(0编辑  收藏  举报