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

     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。

    思路:

      LCA+最大生成树(路的限重越大越好)

    上代码:

    1.

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define INF 1000000000
    #define MAXM 50010
    #define MAXN 10010
    struct node {
        int x,y,v;
    } E[MAXM];
    struct node2 {
        int y,next,v;
    } e[MAXN*2];
    int n,m,q,len;
    int vis[MAXN],f[MAXN],Link[MAXN],deep[MAXN],anc[MAXN][25],w[MAXN][25];
    
    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 cmp(node a,node b) {
        return a.v>b.v;
    }
    
    int find(int x)  {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    
    void insert(int x,int y,int v) {
        e[++len].next=Link[x];
        Link[x]=len;
        e[len].y=y;
        e[len].v=v;
    }
    
    void dfs(int x) { //计算深度 
        vis[x]=1;
        for(int i=1; i<=20; i++) {
            anc[x][i]=anc[anc[x][i-1]][i-1];
            w[x][i]=min(w[x][i-1],w[anc[x][i-1]][i-1]);
        }
        for(int i=Link[x]; i; i=e[i].next)
            if(!vis[e[i].y]) {
                deep[e[i].y]=deep[x]+1;
                anc[e[i].y][0]=x;
                w[e[i].y][0]=e[i].v;
                dfs(e[i].y);
            }
    }
    
    int lca(int x,int y) { //求LCA 
        if(deep[x]<deep[y])  swap(x,y);
        for(int i=20; i>=0; i--)
            if(deep[anc[x][i]]>=deep[y])
                x=anc[x][i];
        if(x==y)  return x;
        for(int i=20; i>=0; i--)
            if(anc[x][i]!=anc[y][i])
                x=anc[x][i],y=anc[y][i];
        return anc[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)) { //1<<i一定为真,所以要求t为真 
                mn=min(mn,w[x][i]);
                x=anc[x][i];
            }
        return mn;
    }
    
    int main() {
        memset(w,127/3,sizeof(w));
        n=read();    m=read();
        for(int i=1; i<=m; i++)  {
            E[i].x=read(); E[i].y=read(); E[i].v=read();
        }
        sort(E+1,E+m+1,cmp);
        for(int i=1; i<=n; i++)  f[i]=i;
        for(int i=1; i<=m; i++) {
            int x=find(E[i].x),y=find(E[i].y);
            if(x!=y) {
                f[x]=y;
                insert(E[i].x,E[i].y,E[i].v);
                insert(E[i].y,E[i].x,E[i].v);
            }
        }
        for(int i=1; i<=n; i++)  if(!vis[i])  dfs(i);
        q=read();
        for(int i=1; i<=q; i++) {
            int x=read(),y=read();
            if(find(x)!=find(y)) {
                printf("-1
    ");
                continue;
            }
            int t=lca(x,y);
            printf("%d
    ",min(ask(x,t),ask(y,t)));
        }
        return 0;
    }
    货车运输1

    2.

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 10010
    #define maxm 50010
    
    int n,m,f[maxn][20],sum[maxn][20],fa[maxn],num,p,dep[maxn],head[maxn];
    bool vis[maxn];
    struct node {
        int f,to,v;
    } a[maxm];
    struct Edge {
        int pre,v,to;
    } e[maxm];
    
    int cmp(node x,node y) {
        return x.v>y.v;
    }
    
    int find(int x) {
        if(fa[x]==x)return fa[x];
        else return fa[x]=find(fa[x]);
    }
    
    int connect(int x,int y) {
        int f1=find(x),f2=find(y);
        if(f1==f2)return 0;
        else fa[f1]=f2;
        return 1;
    }
    
    void Insert(int from,int to,int v) {
        e[++num].v=v;
        e[num].to=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    
    void dfs(int now,int father,int deep) {
        vis[now]=1;
        dep[now]=deep;
        for(int i=head[now]; i; i=e[i].pre) {
            int v=e[i].to;
            if(v==father)continue;
            f[v][0]=now;
            sum[v][0]=e[i].v;
            dfs(v,now,deep+1);
        }
    }
    
    int lca(int x,int y) {
        if(x==y)return 0;
        int ans=0x3f3f3f3f;
        if(dep[x]<dep[y])swap(x,y);
        for(int i=18; i>=0; i--) {
            if(dep[f[x][i]]>=dep[y]&&f[x][i]!=0)
            ans=min(ans,sum[x][i]),x=f[x][i];
        }
        if(x==y)return ans;
        for(int i=18; i>=0; i--) {
            if(f[x][i]!=f[y][i]) {
                ans=min(ans,sum[x][i]);
                ans=min(ans,sum[y][i]);
                x=f[x][i];
                y=f[y][i];
            }
        }
        ans=min(sum[x][0],ans);
        ans=min(sum[y][0],ans);
        return ans;
    }
    
    int main() {
        memset(sum,127/3,sizeof(sum));
        int x,y,z;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=m; i++)scanf("%d%d%d",&a[i].f,&a[i].to,&a[i].v);
        for(int i=1; i<=n; i++)fa[i]=i;
        sort(a+1,a+m+1,cmp);
        int cnt=0;
        for(int i=1; i<=m; i++) {
            if(connect(a[i].f,a[i].to)) {
                Insert(a[i].f,a[i].to,a[i].v);
                Insert(a[i].to,a[i].f,a[i].v);
                cnt++;
                if(cnt==n-1)break;
            }
        }
        for(int i=1; i<=n; i++)if(!vis[i])dfs(i,0,1);
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                if(f[f[i][j-1]][j-1]!=0) {
                    f[i][j]=f[f[i][j-1]][j-1];
                    sum[i][j]=min(sum[i][j-1],sum[f[i][j-1]][j-1]);
                }
        scanf("%d",&p);
        for(int i=1; i<=p; i++) {
            scanf("%d%d",&x,&y);
            if(find(x)!=find(y)) {
                printf("-1
    ");
                continue;
            }
            printf("%d
    ",lca(x,y));
        }
    }
    货车运输2

    自己选的路,跪着也要走完!!!

  • 相关阅读:
    Python学习第75天(js历史和引入,模块复习)
    Python学习第74天(抽屉习题笔记)
    Python学习第73天(shelve模块、习题练习)
    Js查漏补缺02-各种数据类型
    Js查漏补缺01-js学习笔记
    开篇
    小小python欢乐多
    阅读笔记09 个人对于三年来软件工程的一点心得
    14周周博客
    软件杯第二阶段
  • 原文地址:https://www.cnblogs.com/wsdestdq/p/7327489.html
Copyright © 2011-2022 走看看