zoukankan      html  css  js  c++  java
  • codevs 1519 过路费

    时间限制: 1 s
     空间限制: 256000 KB
     题目等级 : 大师 Master
    题目描述 Description

        在某个遥远的国家里,有 n个城市。编号为 1,2,3,…,n。这个国家的政府修建了m 条双向道路,每条道路连接着两个城市。政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值。如:A到B长度为 2,B到C 长度为3,那么开车从 A经过 B到C 需要上交的过路费为 3。
        佳佳是个做生意的人,需要经常开车从任意一个城市到另外一个城市,因此他需要频繁地上交过路费,由于忙于做生意,所以他无时间来寻找交过路费最低的行驶路线。然而, 当他交的过路费越多他的心情就变得越糟糕。 作为秘书的你,需要每次根据老板的起止城市,提供给他从开始城市到达目的城市,最少需要上交多少过路费。

    输入描述 Input Description

        第一行是两个整数 n 和m,分别表示城市的个数以及道路的条数。 
        接下来 m 行,每行包含三个整数 a,b,w(1≤a,b≤n,0≤w≤10^9),表示a与b之间有一条长度为 w的道路。
        接着有一行为一个整数 q,表示佳佳发出的询问个数。 
        再接下来 q行,每一行包含两个整数 S,T(1≤S,T≤n,S≠T), 表示开始城市S 和目的城市T。

    输出描述 Output Description

        输出共q行,每行一个整数,分别表示每个询问需要上交的最少过路费用。输入数据保证所有的城市都是连通的。

    样例输入 Sample Input

    4 5 
    1 2 10 
    1 3 20 
    1 4 100 
    2 4 30 
    3 4 10 

    1 4 
    4 1

    样例输出 Sample Output

    20 
    20

    数据范围及提示 Data Size & Hint

    对于 30%的数据,满足 1≤ n≤1000,1≤m≤10000,1≤q≤100; 
    对于 50%的数据,满足 1≤ n≤10000,1≤m≤10000,1≤q≤10000; 
    对于 100%的数据,满足 1≤ n≤10000,1≤m≤100000,1≤q≤10000;

     
    最小生成树+LCA
    #include <algorithm>
    #include <ctype.h>
    #include <cstdio>
    #define M 205005
    
    void read(int &x)
    {
        x=0;bool f=0;
        register char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=1;
        for(; isdigit(ch);ch=getchar()) x=x*10+ch-'0';
        x=f?(~x)+1:x;
    }
    struct Edge
    {
        int x,y,z;
        bool operator <(Edge a)const
        {
            return z<a.z;
        }
    }e[M];
    struct NewEdge
    {
        int next,to,value;
        NewEdge(int next=0,int to=0,int value=0) : next(next),to(to),value(value) {}
    }edge[M<<1];
    using namespace std;
    int f[M][25],dep[M],dad[M][30],head[M<<1],cnt,n,m,q,fa[M];
    int find_(int x) {return fa[x]==x?x:fa[x]=find_(fa[x]);}
    void ins(int u,int v,int w)
    {
        edge[++cnt]=NewEdge(head[u],v,w);
        head[u]=cnt;  
    }
    void dfs(int x)
    {
        dep[x]=dep[dad[x][0]]+1;
        for(int i=0;dad[x][i];i++)
        {
            dad[x][i+1]=dad[dad[x][i]][i];
            f[x][i+1]=max(f[dad[x][i]][i],f[x][i]);
        }
        for(int u=head[x];u;u=edge[u].next)
        {
            int v=edge[u].to;
            if(dad[x][0]!=v)
            {
                dad[v][0]=x;
                f[v][0]=edge[u].value;
                dfs(v);
            }
        }
    }
    int lca(int x,int y)
    {
        int ans=0;
        if(dep[x]<dep[y]) swap(x,y);
        for(int i=25;i>=0;i--)
        {
            if(dep[dad[x][i]]>=dep[y])
            {
                ans=max(ans,f[x][i]);
                x=dad[x][i];
            }
        }
        if(x==y) return ans;
        for(int i=25;i>=0;i--)
        {
            if(dad[x][i]!=dad[y][i])
            {
                ans=max(ans,f[x][i]);
                ans=max(ans,f[y][i]);
                x=dad[x][i];
                y=dad[y][i];
            }
        }
        return max(max(f[x][0],f[y][0]),ans);
    }
    int main()
    {
        read(n);
        read(m);
        for(int i=1;i<=n;i++)
            fa[i]=i;
        for(int i=1;i<=m;i++)
        {
            read(e[i].x);
            read(e[i].y);
            read(e[i].z);
            if(e[i].x>e[i].y) swap(e[i].x,e[i].y);
        }
        sort(e+1,e+1+m);
        int sum=0;
        for(int i=1;i<=m;i++)
        {
            int fx=find_(e[i].x),fy=find_(e[i].y);
            if(fx!=fy)
            {
                fa[fy]=fx;
                ins(e[i].x,e[i].y,e[i].z);
                ins(e[i].y,e[i].x,e[i].z);
                sum++;
                if(sum==n-1) break;
            }
        }
        dfs(1);
        read(q);
        for(int x,y;q--;)
        {
            read(x);
            read(y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    Reactive Extensions (Rx) 入门(5) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(4) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(3) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(2) —— 安装 Reactive Extensions
    Reactive Extensions (Rx) 入门(1) —— Reactive Extensions 概要
    Xamarin NuGet 缓存包导致 already added : Landroid/support/annotation/AnimRes 问题解决方案
    Android 系统Action大全
    Xamarin Forms 实现发送通知点击跳转
    如何理解灰度发布
    推荐一款分布式微服务框架 Surging
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7300410.html
Copyright © 2011-2022 走看看