• 3287 货车运输


    3287 货车运输

     

    2013年NOIP全国联赛提高组

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
     
     
    题目描述 Description

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

    输入描述 Input Description

    第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
    接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
    接下来一行有一个整数 q,表示有 q 辆货车需要运货。
    接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。

    输出描述 Output Description

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

    样例输入 Sample Input

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

    样例输出 Sample Output

    3
    -1
    3

    数据范围及提示 Data Size & Hint

    对于 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。

     
     

    20分代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 5001
    int g[N][N];
    int n,m,q;
    int main(){
        
        scanf("%d%d",&n,&m);
        memset(g,-1,sizeof g);
        for(int i=1;i<=m;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            g[x][y]=max(g[x][y],z);
            g[y][x]=max(g[y][x],z);
        }
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(i!=j&&g[i][k]!=-1&&g[k][j]!=-1){
                        g[i][j]=max(g[i][j],min(g[i][k],g[k][j]));
                    }
                }
            }
        }
        scanf("%d",&q);
        for(int i=1;i<=q;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d
    ",g[x][y]);
        }
        return 0;
    }

    朴素LCA的AC代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 10010
    int n,m,q,fa[N],fv[N],vi[N],s[N][51],v[N][51];
    struct node{
        int x,y,s;
    }a[N*5];
    inline bool cmp(const node &q,const node &p){
        return q.s>p.s;
    }
    int find(int x){
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    void dfs(int x){
        for(int i=1;i<=s[x][0];i++){
            if(fa[s[x][i]]==s[x][i]){
                fa[s[x][i]]=x;
                fv[s[x][i]]=v[x][i];
                dfs(s[x][i]);
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].s);
        sort(a+1,a+m+1,cmp);
        for(int i=1;i<=n;i++) fa[i]=i;
        for(int i=1;i<=m;i++){
            int fx=find(a[i].x),fy=find(a[i].y);
            if(fx!=fy){
                fa[fx]=fy;
                s[a[i].x][++s[a[i].x][0]]=a[i].y;
                s[a[i].y][++s[a[i].y][0]]=a[i].x;
                v[a[i].x][++v[a[i].x][0]]=a[i].s;
                v[a[i].y][++v[a[i].y][0]]=a[i].s;
            }
        }
        for(int i=1;i<=n;i++) fa[i]=i;
        fa[1]=0;
        dfs(1);
        scanf("%d",&q);
        for(int i=1,x,y;i<=q;i++){
            scanf("%d%d",&x,&y);
            for(int j=1;j<=n;j++) vi[j]=1e8;
            for(int j=x;vi[fa[j]]==1e8&&j;j=fa[j])
                vi[fa[j]]=min(vi[j],fv[j]);
            int tmp=1e8;
            for(int j=y;;j=fa[j]){
                if(vi[j]<1e8||j==x){
                    tmp=min(tmp,vi[j]);break;
                }
                tmp=min(tmp,fv[j]);
                if(fa[j]==j||!j){tmp=-1;break;}
            }
            if(!tmp) tmp=-1;
            printf("%d
    ",tmp);
        }
        return 0;
    }

    倍增LCA就是快!

    AC代码:

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define N 10100
    inline const int read(){
        register int x=0,f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,q,fa[N],dep[N],f[N][21],g[N][21];
    struct node{
        int u,v,w;
        bool operator < (const node &t) const {return w>t.w;}
    }e[N<<1];
    int find(int x){
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    vector<int>p[N],c[N];
    void dfs(int x,int de){
        for(int i=0;i<p[x].size();i++){
            if(!dep[p[x][i]]){
                dep[p[x][i]]=de+1;
                f[p[x][i]][0]=x;
                g[p[x][i]][0]=c[x][i];
                dfs(p[x][i],de+1);
            }
        }
    }
    int lca(int a,int b){
        if(dep[a]<dep[b]) swap(a,b);
        int t=dep[a]-dep[b];
        int ans=0x7fffffff;
        for(int i=0;i<=20;i++){
            if((1<<i)&t){
                ans=min(ans,g[a][i]);
                a=f[a][i];
            }
        }
        if(a==b) return ans;
        for(int i=20;i>=0;i--){
            if(f[a][i]!=f[b][i]){
                ans=min(ans,g[a][i]);
                ans=min(ans,g[b][i]);
                a=f[a][i];
                b=f[b][i];
            }
        }
        return min(ans,min(g[a][0],g[b][0]));
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=m;i++) e[i].u=read(),e[i].v=read(),e[i].w=read();
        for(int i=1;i<=n;i++) fa[i]=i;
        stable_sort(e+1,e+m+1);
        for(int i=1;i<=m;i++){
            int fx=find(e[i].u),fy=find(e[i].v);
            if(fx!=fy){
                fa[fx]=fy;
                p[e[i].u].push_back(e[i].v);
                p[e[i].v].push_back(e[i].u);
                c[e[i].u].push_back(e[i].w);
                c[e[i].v].push_back(e[i].w);
            }
        }
        dep[1]=1;
        dfs(1,1);
        for(int j=1;j<=20;j++){
            for(int i=1;i<=n;i++){
                f[i][j]=f[f[i][j-1]][j-1];
                g[i][j]=min(g[i][j-1],g[f[i][j-1]][j-1]);
            }
        }
        q=read();
        for(int i=1,x,y,tmp;i<=q;i++){
            x=read();y=read();
            if(find(x)!=find(y)){puts("-1");continue;}
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }

     2017-04-06

    /最小值最大:最大生成树找最小边 
    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int N=1e4+5;
    const int M=1e5+5;
    int n,m,Q,fa[N],dep[N],f[N][20],g[N][20];
    struct data{int u,v,w;}a[M];
    struct edge{int v,w,next;}e[M];int tot,head[N];
    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*10+ch-'0';ch=getchar();}
        return x*f;
    }
    bool operator <(const data &a,const data &b){
        return a.w>b.w;
    }
    int find(int x){
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    void add(int x,int y,int z){
        e[++tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
        e[++tot].v=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;
    }
    void dfs(int x){
        for(int i=head[x];i;i=e[i].next){
            if(!dep[e[i].v]){
                dep[e[i].v]=dep[x]+1;
                f[e[i].v][0]=x;
                g[e[i].v][0]=e[i].w;
                dfs(e[i].v);
            }
        }
    }
    int lca(int x,int y){
        if(dep[x]<dep[y]) swap(x,y);
        int t=dep[x]-dep[y],ans=2e9;
        for(int i=0;i<=18;i++){
            if(t&(1<<i)){
                ans=min(ans,g[x][i]);
                x=f[x][i];
            }
        }
        if(x==y) return ans;
        for(int i=18;~i;i--){
            if(f[x][i]!=f[y][i]){
                ans=min(ans,g[x][i]);
                ans=min(ans,g[y][i]);
                x=f[x][i];
                y=f[y][i];
            }
        }
        return min(ans,min(g[x][0],g[y][0]));
    }
    int main(){
        freopen("truck.in","r",stdin);
        freopen("truck.out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=n;i++) fa[i]=i;
        for(int i=1;i<=m;i++) a[i].u=read(),a[i].v=read(),a[i].w=read();
        sort(a+1,a+m+1);
        for(int i=1,k=0,x,y,fx,fy;i<=m;i++){
            x=a[i].u,y=a[i].v;
            fx=find(x);fy=find(y);
            if(fx!=fy){
                fa[fx]=fy;
                add(x,y,a[i].w);
                if(++k==n-1) break;
            }
        }
        dep[1]=1;dfs(1);
        for(int j=1;j<=18;j++){
            for(int i=1;i<=n;i++){
                f[i][j]=f[f[i][j-1]][j-1];
                g[i][j]=min(g[i][j-1],g[f[i][j-1]][j-1]);
            }
        }
        Q=read();
        for(int i=1,x,y;i<=Q;i++){
            x=read();y=read();
            if(find(x)!=find(y)) puts("-1");
            else printf("%d
    ",lca(x,y));
        }
        return 0;
    }
  • 相关阅读:
    javaScript面向对象继承方法经典实现
    javascript面向对象之Javascript 继承
    js面向对象 多种创建对象方法小结
    JavaScript 三种创建对象的方法
    正常上线的流程
    java.lang.NoClassDefFoundError: javax/servlet/ServletInputStream
    org/eclipse/jetty/util/component/Container$Listener
    java.io.IOException: Cannot find any registered HttpDestinationFactory from the Bus.
    java.lang.NoClassDefFoundError: javax/wsdl/extensions/ElementExtensible
    java.lang.ClassNotFoundException: org.objectweb.asm.ClassWriter
  • 原文地址:https://www.cnblogs.com/shenben/p/5635712.html
Copyright © 2020-2023  润新知