zoukankan      html  css  js  c++  java
  • P1967 货车运输

      一道最大生成树和LCA的结合问题。

      有几个要注意的:

        1.链式前向星不能直接排序,只能借助另一个结构体完成(详细见代码)

        2.par,fa,w都要处理,其中par可以一开始就处理,而fa在dfs中处理,而w跟着fa一起更新即可。

      剩下的就没什么了……

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define maxn 100005
    #define INF 9999999
    struct first
    {
        int x,y,z;
    } fir[5*maxn];
    struct second
    {
        int to,nxt,w;
    } now[5*maxn];
    int head[maxn],dep[maxn],par[maxn],fa[maxn][21],w[maxn][21];
    int cnt,n,m,q;
    bool vis[maxn];
    bool cmp(first a,first b)
    {
        return a.z>b.z;
    }
    void Deal_first()
    {
        sort(fir+1,fir+1+m,cmp);
        for(int i=1; i<=n; i++)
            par[i]=i;
    }
    void add(int a,int b,int c)
    {
        now[++cnt].to=b;
        now[cnt].nxt=head[a];
        head[a]=cnt;
        now[cnt].w=c;
    }
    void dfs(int u,int father)
    {
        for(int i = 1;i <= 20;i++)
             fa[u][i] = fa[fa[u][i - 1]][i - 1],w[u][i] = min(w[u][i - 1],w[fa[u][i - 1]][i - 1]);//只能这么表示,总不能w[u][i]=w[u][i]吧; 
        for(int i=head[u]; i; i=now[i].nxt)
        {
            int to = now[i].to;
            if(vis[to])
                continue;
            dep[to] = dep[u] + 1;
            vis[to] = 1;
            fa[to][0] = u;
            w[to][0]=now[i].w;
            dfs(to,u);
        }
        return ;
    }
    int find(int x)
    {
        return par[x] == x ? x : par[x] = find(par[x]);
    }
    void kruskal()
    {
        for(int i=1; i<=m; i++)
        {
            int u = fir[i].x,v = fir[i].y,w = fir[i].z;
            if(find(u) == find(v))
                continue;
            par[find(u)]=find(v);
            add(u,v,w);
            add(v,u,w);
        }
        return ;
    }
    int lca(int x,int y)
    {
        if(find(x)!=find(y))
            return -1;
        int ans=INF;
        if(dep[x]<dep[y])
            swap(x,y);
        for(int i=20; i>=0; i--)
        {
            if(dep[fa[x][i]]>=dep[y])
            {
                ans=min(ans,w[x][i]);
                x=fa[x][i];
            }
            if(x==y)
                return ans;
        }
        for(int i=20; i>=0; i--)
        {
            if(fa[x][i]!=fa[y][i])
            {
                ans=min(min(w[x][i],w[y][i]),ans);
                x=fa[x][i];
                y=fa[y][i];
            }
        }
        ans=min(ans,min(w[x][0],w[y][0]));
        return ans;
    }
    int main()
    {
        int x,y,z;
        memset(w,0x3f,sizeof(w));
        scanf("%d%d",&n,&m);
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            fir[i].x=x;
            fir[i].y=y;
            fir[i].z=z;
        }
        Deal_first();
        kruskal();
        for(int i=1; i<=n; i++)
            if(!vis[i])
            {
                vis[i] = 1;
                dfs(i,0);
            }
        scanf("%d",&q);
        for(int i=1; i<=q; i++)
        {
            scanf("%d%d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }

      最后希望这个题解能帮到大家>\<~~~

  • 相关阅读:
    JQuery checkbox全选多次点击后无效解决方法
    mongodb更新数据
    EasyUI--datebox设置默认时间
    转载:MyEclipse中防止代码格式化时出现换行的情况的设置
    Java 多维数组 按某列 排序
    Java Entry使用
    matlab使用reshape时按照列优先原则取元素和摆放元素
    boost--signal
    boost--function
    boost--bind
  • 原文地址:https://www.cnblogs.com/popo-black-cat/p/10046330.html
Copyright © 2011-2022 走看看