zoukankan      html  css  js  c++  java
  • HUD-2586(LCA板子)

    我就想存个板子而已

    倍增法:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5;
    struct Edge
    {
        int to;
        int d;
        int next;
    }edge[maxn*2];
    int head [maxn],tot,in[maxn];
    void addedge(int u,int v,int w)
    {
        edge[tot].to=v;
        edge[tot].next=head[u];
        edge[tot].d=w;
        head[u]=tot++;
    }
    void init ()
    {
        tot=0;
        memset(in,0,sizeof(in));
        memset(head,-1,sizeof(head));
    }
    int fa[maxn][30];
    int deg[maxn],d[maxn];
    void BFS(int root)
    {
        queue <int > que;
        deg[root]=d[root]=0;
        fa[root][0]=root;
        que.push(root);
        while(!que.empty())
        {
            int tmp=que.front();
            que.pop();
            for(int i=1;i<30;i++)
                fa[tmp][i]=fa[fa[tmp][i-1]][i-1];
            for(int i=head[tmp];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(v==fa[tmp][0])continue;
                deg[v]=deg[tmp]+1;
                d[v]=d[tmp]+edge[i].d;
                fa[v][0]=tmp;
                que.push(v);
            }
        }
    }
    int LCA (int u,int v)
    {
        if(deg[u]>deg[v])swap(u,v);
        int hu=deg[u],hv=deg[v];
        int tu=u,tv=v;
        for(int det=hv-hu,i=0;det;det>>=1,i++)
        {
            if(det&1)
                tv=fa[tv][i];
        }
        if(tu==tv)return tu;
        for(int i=30-1;i>=0;i--)
        {
            if(fa[tu][v]==fa[tv][i])continue;
            tu=fa[tu][i];
            tv=fa[tv][i];
        }
        return fa[tu][0];
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            init();
            for(int i=0;i<n-1;i++)
            {
                int u,v,val;
                scanf("%d%d%d",&u,&v,&val);
                addedge(u,v,val);
                addedge(v,u,val);
                in[v]=1;
            }
            int tt;
            for(int i=1;i<=n;i++)
            {
                if(!in[i]){tt=i;break;}
            }
            BFS(tt);
            while(m--)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                printf("%d
    ",d[u]+d[v]-2*d[LCA(u,v)]);
            }
        }
    }

    Tarjan:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=40000+100;
    int head[N];
    int vis[N];
    int parent[N];
    int ans[N];
    int cnt;
    vector<int>q[N];
    vector<int>Q[N];
    int dis[N];
    int n;
    int ancestor[N];
    struct node{
        int to,next,w;
    }edge[2*N+10];
    void init(){
        cnt=0;
        memset(ans,0,sizeof(ans));
        memset(dis,0,sizeof(dis));
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<=n;i++){
            parent[i]=i;
            Q[i].clear();
            q[i].clear();
        }
    }
    void add(int u,int v,int w){
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    int find(int x){
        int r=x;
        while(r!=parent[x])r=parent[r];
        int i=x;
        int j;
        while(parent[i]!=r){
            j=parent[i];
            parent[i]=r;
            i=j;
        }
        return r;
    }
    void Union(int x,int y){
        x=find(x);
        y=find(y);
        if(x!=y)parent[y]=x;
    }
    void Tarjan(int x,int w){
        vis[x]=1;
        dis[x]=w;
        //cout<<dis[x]<<endl;
        for(int i=head[x];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(vis[v])continue;
            Tarjan(v,w+edge[i].w);
            Union(x,v);
            ancestor[find(x)]=x;
        }
        for(int i=0;i<q[x].size();i++){
            int u=q[x][i];
            if(vis[u]){
                int t=ancestor[find(u)];
                ans[Q[x][i]]=dis[x]+dis[u]-dis[t]*2;
            }
        }
    }
    int main(){
        int m;
        int t;
        scanf("%d",&t);
        while(t--){
            init();
            scanf("%d%d",&n,&m);
            int u,v,w;
            for(int i=0;i<n-1;i++){
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);
                add(v,u,w);
            }
            for(int i=0;i<m;i++){
                scanf("%d%d",&u,&v);
                q[u].push_back(v);
                q[v].push_back(u);
                Q[u].push_back(i);
                Q[v].push_back(i);
            }
            Tarjan(1,0);
           // for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
            //cout<<endl;
            for(int i=0;i<m;i++){
                   // cout<<4<<endl;
                cout<<ans[i]<<endl;
            }
        }
    }
  • 相关阅读:
    pandas 分组过滤
    bert fine tuning方法
    对字典进行排序
    1*1的卷积的作用
    使用Conv代替全连接层FC
    训练笔记
    javascript 正则分组捕捉
    谷歌浏览器 喔唷,崩溃啦
    sed awk
    c# 通过程序修改hosts文件
  • 原文地址:https://www.cnblogs.com/kayiko/p/12126300.html
Copyright © 2011-2022 走看看