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

    题目描述

    A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

    输入输出格式

    输入格式:

     

    输入文件名为 truck.in。

    输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道

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

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

    接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意: x 不等于 y 。

     

    输出格式:

     

    输出文件名为 truck.out。

    输出共有 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,000。

    题目大意:求两点之间路径上最短边的最大值。

    题解:

    方法一、Kruskal建最大生成树+倍增lca

    方法二、Kruskal建最大生成树+树链剖分

    方法三、Kruskal重构树+树剖求lca

    代码

    一、黄学长的

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define inf 0x7fffffff
    using namespace std;
    int n,m,q,cnt,tot,deep[10001],head[10001],f[10001],fa[10001][17],d[10001][17];
    bool vis[10001];
    struct edge{int x,y,v;}a[50001];
    struct e{int next,to,v;}e[20001];
    void ins(int u,int v,int w)
    {e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].v=w;}
    void insert(int u,int v,int w)
    {ins(u,v,w);ins(v,u,w);}
    int find(int x)
    {return f[x]==x?x:f[x]=find(f[x]);}
    bool cmp(edge a,edge b)
    {return a.v>b.v;}
    void dfs(int x)
    {
        vis[x]=1;
        for(int i=1;i<=16;i++)
        {
            if(deep[x]<(1<<i))break;
            fa[x][i]=fa[fa[x][i-1]][i-1];
            d[x][i]=min(d[x][i-1],d[fa[x][i-1]][i-1]);
        }
        for(int i=head[x];i;i=e[i].next)
        {
            if(vis[e[i].to])continue;
            fa[e[i].to][0]=x;
            d[e[i].to][0]=e[i].v;
            deep[e[i].to]=deep[x]+1;
            dfs(e[i].to);
        }
    }
    int lca(int x,int y)
    {
        if(deep[x]<deep[y])swap(x,y);
        int t=deep[x]-deep[y];
        for(int i=0;i<=16;i++)
            if((1<<i)&t)x=fa[x][i];
        for(int i=16;i>=0;i--)
        {
            if(fa[x][i]!=fa[y][i])
            {x=fa[x][i];y=fa[y][i];}
        }
        if(x==y)return x;
        return fa[x][0];
    }
    int ask(int x,int f)
    {
        int mn=inf;
        int t=deep[x]-deep[f];
        for(int i=0;i<=16;i++)
        {
            if(t&(1<<i))
            {
               mn=min(mn,d[x][i]);
               x=fa[x][i];
            }
        }
        return mn;
    }
    int main()
    {
        memset(d,127/3,sizeof(d));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)f[i]=i;
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);
        sort(a+1,a+m+1,cmp);
        for(int i=1;i<=m;i++)
        {
            int x=a[i].x,y=a[i].y;
            int p=find(a[i].x),q=find(a[i].y);
            if(p!=q)
            {
                f[p]=q;
                insert(x,y,a[i].v);
                tot++;if(tot==n-1)break;
            }
        }
        for(int i=1;i<=n;i++)if(!vis[i])dfs(i);
        scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            int x,y;scanf("%d%d",&x,&y);
            if(find(x)!=find(y)){printf("-1
    ");continue;}
            else 
            {
                int t=lca(x,y);
                printf("%d
    ",min(ask(x,t),ask(y,t)));
            }
        }
        return 0;
    }

    二、

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #define maxn 50005
    #define inf 0x7fffffff
    using namespace std;
    int n,m,sumedge,cnt,q;
    int head[maxn],fe[maxn],deep[maxn],wson[maxn],top[maxn];
    int fa[maxn],size[maxn],dad[maxn],real[maxn],tpos[maxn];
    struct Edge{
        int x,y,z,nxt;
        Edge(int x=0,int y=0,int z=0,int nxt=0):
            x(x),y(y),z(z),nxt(nxt){}
    }edge[maxn<<1];
    
    struct E{
        int x,y,z;
    //    bool operator < (const E &x)const {return z>x.z;}
    }e[maxn];
    
    void add(int x,int y,int z){
        edge[++sumedge]=Edge(x,y,z,head[x]);
        head[x]=sumedge;
    }
    
    struct Tree{
        int l,r,maxv,minv;
    }tr[maxn<<2];
    
    int f(int x){
        return fa[x]==x?x:fa[x]=f(fa[x]);
    }
    bool cmp(E a,E b){
        return a.z>b.z;
    }
    void Kruskal(){
        sort(e+1,e+m+1,cmp);
        int tot=0;
        for(int i=1;i<=m;i++){
            int fx=f(e[i].x),fy=f(e[i].y);
            if(fx!=fy){
                fa[fx]=fy;
                add(e[i].x,e[i].y,e[i].z);
                add(e[i].y,e[i].x,e[i].z);
                if(++tot==n-1)break;
            }
        }
    }
    void dfs1(int x,int fu){
        size[x]=1;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(v==fu)continue;
            dad[v]=x;fe[v]=edge[i].z;deep[v]=deep[x]+1;
            dfs1(v,x);
            size[x]+=size[v];
            if(size[v]>size[wson[x]])wson[x]=v;
        }
    }
    void dfs2(int x,int fr){
        tpos[x]=++cnt;real[cnt]=x;top[x]=fr;
        if(wson[x])dfs2(wson[x],fr);
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(v!=dad[x]&&v!=wson[x])dfs2(v,v);
        }
    }
    
    void pushup(int rt){
        tr[rt].maxv=max(tr[rt<<1].maxv,tr[rt<<1|1].maxv);
        tr[rt].minv=min(tr[rt<<1].minv,tr[rt<<1|1].minv);
        return;
    }
    
    void build(int rt,int l,int r){
        tr[rt].l=l;tr[rt].r=r;
        if(l==r){
            tr[rt].minv=tr[rt].maxv=fe[real[l]];
            return ;
        }
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
        pushup(rt);
    }
    
    /*int query_min(int rt,int l,int r,int ql,int qr){
        if(l>r)return 2147483647;
        if(ql<=l&&r<=qr){
            return tr[rt].minv;
        //    cout<<"lalal  "<<tr[rt].minv<<endl;
        }
        int mid=(l+r)>>1;ans=inf;
        if(qr<=mid)return query_min(rt<<1,l,mid,ql,qr);
        else if(ql>mid)return query_min(rt<<1|1,mid+1,r,ql,qr);
        else return min(query_min(rt<<1,l,mid,ql,qr),query_min(rt<<1|1,mid+1,r,ql,qr));
    
        if (ql<=mid)return query_min(rt<<1,l,mid,ql,qr);
        if (qr>mid)return query_min(rt<<1|1,mid+1,r,ql,qr);
    }
    */
    int query_min(int o,int l,int r,int ql,int qr){
        if (l>r) return 2147483647;
        int mid=(l+r)/2,ans=inf;
        if (ql<=l&&r<=qr)return tr[o].minv;
        if (ql<=mid)ans=min(ans,query_min(o*2,l,mid,ql,qr));
        if (qr>mid)ans=min(ans,query_min(o*2+1,mid+1,r,ql,qr));
        //pushup(o);
        return ans;
    }
    int qmin(int u,int v){
        int ans=inf;
        while(top[u]!=top[v]){
            if(deep[top[u]]>deep[top[v]])swap(u,v);
            ans=min(ans,query_min(1,1,n,tpos[top[v]],tpos[v]));
            v=dad[top[v]];
        }
        if(deep[u]>deep[v])swap(u,v);
        ans=min(ans,query_min(1,1,n,tpos[u]+1,tpos[v]));
    }
    int main(){
        memset(fe,-1,sizeof(fe));//**
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
        for(int i=1;i<=n;i++)fa[i]=i;
        Kruskal();
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n);
        scanf("%d",&q);
        while(q--){
            int x,y;
            scanf("%d%d",&x,&y);
            if(f(x)!=f(y))printf("-1
    ");
            else printf("%d
    ",qmin(x,y));
        }
        return 0;
    }

    三、

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define maxm 500008
    #define maxn 100008
    
    using namespace std;
    
    int n,m,x,y,z,tot,sumedge,nn,q;
    int head[maxn],fa[maxn],size[maxn],dad[maxn],top[maxn],deep[maxn],w[maxn];
    
    struct E{
        int x,y,z;
    ///    bool operator < (const E &a)const{return z>a.z;}
    }e[maxm];
    
    struct Edge{
        int x,y,nxt;
        Edge(int x=0,int y=0,int nxt=0):
            x(x),y(y),nxt(nxt){}
    }edge[maxn<<1];
    
    void add(int x,int y){
        edge[++sumedge]=Edge(x,y,head[x]);
        head[x]=sumedge;
    }
    
    bool cmp(E a,E b){return a.z>b.z;}
    
    int f(int x){return fa[x]==x?x:fa[x]=f(fa[x]);}
    
    void dfs(int x){
        size[x]=1;deep[x]=deep[dad[x]]+1;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(v!=dad[x]){
                dad[v]=x;
                dfs(v);
                size[x]+=size[v];
            }
        }
    }
    
    void dfs2(int x){
        int s=0;
        if(!top[x])top[x]=x;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(v!=dad[x]&&size[v]>size[s])s=v;
        }
        if(s){
            top[s]=top[x];
            dfs2(s);
        }
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(v!=dad[x]&&v!=s)dfs2(v);
        }
    }
    
    int lca(int x,int y){
        for(;top[x]!=top[y];){
            if(deep[top[x]]>deep[top[y]])
            swap(x,y);
            y=dad[top[y]];
        }
        if(deep[x]>deep[y])swap(x,y);
        return w[x];
    }
    
    int main(){
        scanf("%d%d",&n,&m);nn=n;
        for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
        for(int i=1;i<=n;i++)fa[i]=i;
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=m;i++){
            int fx=f(e[i].x),fy=f(e[i].y);
            if(fx!=fy){
                nn++;
                add(nn,fx);add(fx,nn);
                add(fy,nn);add(nn,fy);
                fa[nn]=nn;fa[fx]=nn;fa[fy]=nn;
                ++tot;w[nn]=e[i].z;
                if(tot==n-1)break;
            }
        }
        dfs(nn);dfs2(nn);
        scanf("%d",&q);
        for(int i=1;i<=q;i++){
            scanf("%d%d",&x,&y);
            if(f(x)!=f(y)){
                printf("-1
    ");
                continue;
            }
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
  • 相关阅读:
    remove white space from read
    optimize the access speed of django website
    dowload image from requests
    run jupyter from command
    crawl wechat page
    python version 2.7 required which was not found in the registry windows 7
    health
    alternate rows shading using conditional formatting
    word
    【JAVA基础】static 关键字
  • 原文地址:https://www.cnblogs.com/zzyh/p/7503164.html
Copyright © 2011-2022 走看看