zoukankan      html  css  js  c++  java
  • [NOIP 2013]货车运输

    题目传送门

    因为要求最长集合线段中的最小值所以果断使用最大生成树,因为给定的是张图,无法确定唯一路径,而在树上就是了

    再去求相当于两点分别为端点的链上最小值

    以前写过树上路径,详情请点击(T1)

    所以这时就成了一道板子题了

    注意:这或许不仅仅只有一棵树,遍历找没有访问过的点重新当根即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    inline int read()
    {
        int f=1,ans=0;char c;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return ans*f;
    }
    int f[10001],n,m;
    struct node{
        int u,v,w,nex;
    }x[50001];
    int head[10001],cnt;
    void add(int u,int v,int w)
    {
        x[cnt].u=u,x[cnt].v=v,x[cnt].w=w,x[cnt].nex=head[u],head[u]=cnt++;
    }
    struct node1{
        int a,b,c;
    }s[50001];
    int sry;
    bool cmp(node1 x1,node1 x2)
    {
        return x1.c>x2.c;
    }
    int find(int x)
    {
        if(f[x]==x) return x;
        return f[x]=find(f[x]);
    }
    int fa[10001][21];
    int minn[10001][21],deep[10001];
    void dfs(int f,int fath)
    {  
        fa[f][0]=fath;
        deep[f]=deep[fath]+1;
        for(int i=1;(1<<i)<=deep[f];i++)
        {
            fa[f][i]=fa[fa[f][i-1]][i-1];
            minn[f][i]=min(minn[f][i-1],minn[fa[f][i-1]][i-1]);
        }
        for(int i=head[f];i!=-1;i=x[i].nex)
        {
            if(x[i].v==fath) continue;
            minn[x[i].v][0]=x[i].w;
            dfs(x[i].v,f);
        }
    }
    int q;
    int lca(int u,int v)
    {
        if(deep[u]==0||deep[v]==0) return -1;
        if(find(u)!=find(v)) return -1;
        int ans=2<<30-1;
        if(deep[u]<deep[v]) swap(u,v);
        for(int i=20;i>=0;i--)
            if(deep[u]-(1<<i)>=deep[v])
            {
                ans=min(ans,minn[u][i]);
                u=fa[u][i];
            }
        if(u==v)  return ans;
        for(int i=20;i>=0;i--)
        {
            if(fa[u][i]==fa[v][i]) continue;
            ans=min(ans,minn[u][i]),u=fa[u][i];
            ans=min(ans,minn[v][i]),v=fa[v][i]; 
        }
        ans=min(ans,minn[u][0]),u=fa[u][0];
        ans=min(ans,minn[v][0]),v=fa[v][0];
        return ans;
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        n=read(),m=read();
        for(int i=1;i<=n;i++) f[i]=i; 
        for(int i=1;i<=m;i++) s[i].a=read(),s[i].b=read(),s[i].c=read(); 
        sort(s+1,s+m+1,cmp);
        for(int i=1;i<=m;i++)
        {
            int t1=find(s[i].a),t2=find(s[i].b);
            if(t1!=t2)
            {
                f[t2]=t1;
                sry++;
                add(s[i].a,s[i].b,s[i].c),add(s[i].b,s[i].a,s[i].c);
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(deep[i]==0) dfs(i,0);
        } 
        q=read();
        for(int i=1;i<=q;i++)
        {
            int u=read(),v=read();
            printf("%d
    ",lca(u,v)); 
        }
    }
  • 相关阅读:
    File
    Include and Require
    Date and Time
    css3的nth-child选择器使用示例
    document.title
    php获取从百度搜索进入网站的关键词的详细代码
    Iphone手机、安卓手机浏览器控制默认缩放大小的方法
    离线宝调用
    织梦DedeCMS网站地图模板
    禁止选择文本和禁用右键 v3.0
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/9550099.html
Copyright © 2011-2022 走看看