• [NOIP2013]货车运输


    1439. [NOIP2013]货车运输

    http://cogs.pro/cogs/problem/problem.php?pid=1439

    ★★☆   输入文件:truck.in   输出文件:truck.out   简单对比
    时间限制:1 s   内存限制:128 MB

    【题目描述】

    【来源】

    CCF全国信息学奥林匹克联赛(NOIP2013)复赛Day1

    首先,可以证明,所有货车都可以只在最大生成树上跑,并不影响答案。(考虑到最大生成树的定义)
    求出最大生成树后,问题转化为,q个询问,每个询问问一条路径上的最小边权。
    可以用倍增来做。预处理f[u][k](意义同LCA中),l[u][k]表示u到u的2^k级祖先的路径上最小的边权值。
    可以在求LCA的过程中直接求出路径上的最小边权。
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define maxn 10010
    #define maxm 50010
    int n,m,f[maxn][20],sum[maxn][20],fa[maxn],num,p,dep[maxn],head[maxn]; 
    bool vis[maxn];
    struct node{
        int f,to,v;
    }a[maxm];
    struct Edge{
        int pre,v,to;
    }e[maxm];
    int cmp(node x,node y){return x.v>y.v;}
    int find(int x){
        if(fa[x]==x)return fa[x];
        else return fa[x]=find(fa[x]);
    }
    int connect(int x,int y){
        int f1=find(x),f2=find(y);
        if(f1==f2)return 0;
        else fa[f1]=f2;return 1;
    }
    void Insert(int from,int to,int v){
        e[++num].v=v;
        e[num].to=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    void dfs(int now,int father,int deep){
        vis[now]=1;
        dep[now]=deep;
        for(int i=head[now];i;i=e[i].pre){
            int v=e[i].to;
            if(v==father)continue;
            f[v][0]=now;
            sum[v][0]=e[i].v;
            dfs(v,now,deep+1);
        }
    }
    int lca(int x,int y){
        if(x==y)return 0;
        int ans=0x3f3f3f3f;
        if(dep[x]<dep[y])swap(x,y);
        for(int i=18;i>=0;i--){
            if(dep[f[x][i]]>=dep[y]&&f[x][i]!=0)ans=min(ans,sum[x][i]),x=f[x][i];
        }
        if(x==y)return ans;
        for(int i=18;i>=0;i--){
            if(f[x][i]!=f[y][i]){
                ans=min(ans,sum[x][i]);
                ans=min(ans,sum[y][i]);
                x=f[x][i];y=f[y][i];
            }
        }
        ans=min(sum[x][0],ans);ans=min(sum[y][0],ans);
        return ans;
    }
    int main(){
        //freopen("Cola.txt","r",stdin);
        freopen("truck.in","r",stdin);
        freopen("truck.out","w",stdout);
        memset(sum,127/3,sizeof(sum));
        int x,y,z;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].f,&a[i].to,&a[i].v);
        for(int i=1;i<=n;i++)fa[i]=i;
        sort(a+1,a+m+1,cmp);int cnt=0;
        for(int i=1;i<=m;i++){
            if(connect(a[i].f,a[i].to)){
                Insert(a[i].f,a[i].to,a[i].v);
                Insert(a[i].to,a[i].f,a[i].v);
                cnt++;if(cnt==n-1)break;
            }
        }
        for(int i=1;i<=n;i++)if(!vis[i])dfs(i,0,1);
        for(int j=1;(1<<j)<=n;j++)
            for(int i=1;i<=n;i++)
                if(f[f[i][j-1]][j-1]!=0){
                    f[i][j]=f[f[i][j-1]][j-1];
                    sum[i][j]=min(sum[i][j-1],sum[f[i][j-1]][j-1]);
                }
        scanf("%d",&p);
        for(int i=1;i<=p;i++){
            scanf("%d%d",&x,&y);
            if(find(x)!=find(y)){printf("-1
    ");continue;}
            printf("%d
    ",lca(x,y));
        }
    }
  • 相关阅读:
    Android应用开发笔记——打造自己的标签栏
    ZeroMQ 的模式[转]
    安装python/wingware
    新手该如何学python怎么学好python?
    membase 简介
    前端学习网站推荐
    签了工作之后才发现,自己太草率了.....我看过的关于职业规划最好最全面的一篇文章[转]
    Nagio监控系统介绍
    thread_union位置
    音频采样位数问题
  • 原文地址:https://www.cnblogs.com/thmyl/p/6817399.html
Copyright © 2020-2023  润新知