貨車運輸-lca

LCA入門題————————————————————————————————————————————-

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,q,hd[10005],cnt,fa[10005],dep[10005],ru[10005],rt;
int xa,ya,f[10005][20],w[10005][20];
struct nod{
    int x,y,z;
}a[10005];//
struct Edge{
    int to,nxt,w;
}eg[20005];
bool cmp(nod p,nod q)
{
    return p.z>q.z;
}
int find(int x)
{
    if(x==fa[x]) return x;
    return fa[x]=find(fa[x]);
}
void add(int x,int y,int z)
{
    cnt++;
    eg[x].to=y;
    eg[x].w=z;
    eg[x].nxt=hd[x];
    hd[x]=cnt;
}
void krus()
{
    for(int i=1;i<=n;i++)
        fa[i]=i;
    sort(a+1,a+m+1,cmp);
    for(int i=1;i<=m;i++)
    {
        int u=find(a[i].x);
        int v=find(a[i].y);
        if(u!=v)
        {
            fa[v]=u;ru[v]++; 
            //重新建圖
            add(a[i].x,a[i].y,a[i].z);
            add(a[i].y,a[i].x,a[i].z);
        }
        if(cnt==n-1) break;//最大生成樹建立成功 
    }
}
void dfs(int u,int d)
{
    dep[u]=d;
    for(int i=hd[u];i;i=eg[i].nxt)
    {
        int v=eg[i].to;
        if(v!=f[u][0])//兒子不是自己的父親
        {
            f[v][0]=u;
            w[v][0]=eg[i].w;
            dfs(v,d+1); 
        } 
    }
}
int lca(int x,int y)
{
    if(dep[x]<dep[y])swap(x,y);
    int s=0x3f3f3f3f;
    for(int i=20;i>=0;i--)
    {
        if(dep[x]>dep[y])
        {
            s=min(s,w[x][i]);
            x=f[x][i];
        }
    }
    if(x==y) return s;
    for(int i=20;i>=0;i++)
        if(f[x][i]!=f[y][i])
        {
            s=min(s,min(w[x][i],w[y][i]));
            x=f[x][i];
            y=f[y][i];
        }
    s=min(s,min(w[x][0],w[y][0]));
    return s;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    krus();//建立一棵樹,最大生成樹 
    for(int i=1;i<=n;i++){
        if(ru[i]==0) {
            rt=i;break;
        }
    }
    dfs(rt,0); 
    for(int i=1;i<=n;i++)
        for(int j=1;j<=20;j++)
        {
            f[i][j]=f[f[i][j-1]][j-1];//i向上跳j步=i,f[i][j]向上跳j-1步
            w[i][j]=min(w[i][j-1],w[f[i][j-1]][j-1]);    
        } 
    scanf("%d",&q);
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&xa,&ya);
        if(find(xa)!=find(ya))
            printf("%d\n",-1);
        else
            printf("%d\n",lca(xa,ya));
    }        
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章