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

    题目描述

    (A)国有(n)座城市,编号从(1)(n),城市之间有(m)条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有

    (q)辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

    输入格式

    第一行有两个用一个空格隔开的整数(n),(m)表示 (A) 国有(n)座城市和(m)条道路。

    接下来(m)行每行3个整数(x),(y),(z)每两个整数之间用一个空格隔开,表示从(x)号城市到(y)号城市有一条限重为z的道路。注意:(x)不等于 (y),两座城市之间可能有多条道路。

    接下来一行有一个整数 (q),表示有 $q $辆货车需要运货。

    接下来 (q) 行,每行两个整数 (x)(y),之间用一个空格隔开,表示一辆货车需要从 (x) 城市运输货物到(y)城市。
    输出格式

    共有(q)行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出(−1)
    输入输出样例

    输入 #1

    4 3
    1 2 4
    2 3 3
    3 1 1
    3
    1 3
    1 4
    1 3

    输出 #1

    3
    -1
    3

    说明/提示

    对于30%的数据,(0<n<1,000,0<m<10,000,0<q<1,000;)

    对于 60%的数据,(0<n<1,000,0<m<50,000,0<q<1,000;)

    对于 100%的数据,(0<n<10,000,0<m<50,000,0<q<30,000,0≤z≤100,0000;)

    代码

    我们通过构造kruskal重构树,在树上查询两点lca的点权值,即为答案。

    关于kruskal重构树操作

    如将边权按降序排序
    则LCA(u,v)的权值代表 原图 u到v路径上最大边权的最小值

    如将边权按升序排序
    则LCA(u,v)的权值代表 原图 u到v路径上最小边权的最大值

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=200000+100,maxm=200000+100,md=20+5;
    int head[maxn],val[maxn],f[maxn],dep[maxn],lg[maxn]; 
    int ff[maxn][md];
    int size=0,cnt=0;
    struct tree
    {
        int to,next;
    }e[maxm<<1];
    struct edge
    {
        int u,v,val;
    }E[maxm<<1];
    int n,m;
    void init()
    {
        for(int i=1;i<=n;i++)
        f[i]=i;
    }
    int find(int x)
    {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    void addedge(int u,int v)
    {
        e[++size].to=v;e[size].next=head[u];head[u]=size;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    bool cmp(const edge&a,const edge&b)
    {
        return a.val>b.val;
    }
    void kruskal()
    {
        for(int i=1;i<=m;i++)
        {
            int u=E[i].u,v=E[i].v;
            int fu=find(u),fv=find(v);
            if(fu!=fv)
            {
            cnt++;
            f[cnt]=f[fu]=f[fv]=cnt;
            val[cnt]=E[i].val;
            addedge(cnt,fu);addedge(fu,cnt);
            addedge(fv,cnt);addedge(cnt,fv);
            }
    
        }
    }
    void dfs(int u,int fa)
    {
        dep[u]=dep[fa]+1;
        ff[u][0]=fa;
        for(int i=1;i<=lg[dep[u]];i++)
        ff[u][i]=ff[ff[u][i-1]][i-1];
        for(int i=head[u];i;i=e[i].next)
        {
            int to=e[i].to;
            if(to==fa)continue;
            dfs(to,u);
        }
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])
        swap(x,y);
        while(dep[x]>dep[y])
        x=ff[x][lg[dep[x]-dep[y]]];
        if(x==y)
        return x;
        for(int i=lg[dep[x]];i>=0;i--)
        if(ff[x][i]!=ff[y][i])x=ff[x][i],y=ff[y][i];
        return ff[x][0];
    }
    int main()
    {
        n=read(),m=read();cnt=n;
        init();
        for(int i=1;i<=m;i++)
        E[i].u=read(),E[i].v=read(),E[i].val=read();
        sort(E+1,E+1+m,cmp);
        kruskal();
        for(int i=1;i<=n;i++)
        lg[i]=lg[i-1]+(1<<(lg[i-1]+1)==i);
        for(int i=1;i<=cnt;i++)
        if(!dep[i])
        dfs(find(i),0); 
        int k=read();
        for(int i=1;i<=k;i++)
        {
            int x=read(),y=read();
            if(find(x)!=find(y))printf("-1
    ");
            else printf("%d
    ",val[lca(x,y)]);
        }
        return 0;
    }
    
  • 相关阅读:
    jQuery(3)——DOM操作
    jQuery(2)——选择器
    jQuery(1)——了解jQuery
    JavaScript(10)——Ajax以及跨域处理
    JavaScript(9)——call与apply
    JavaScript(8)——JSON
    JavaScript(7)——事件2.0
    JavaScript(6)——事件1.0
    JavaScript(5)——DOM
    spring mvc+spring+mybatis搭建javaWeb项目时遇到的一些问题
  • 原文地址:https://www.cnblogs.com/DriverBen/p/10734032.html
Copyright © 2011-2022 走看看