zoukankan      html  css  js  c++  java
  • [luogu 1967]货车运输

    货车运输

    题目描述

    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<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 using namespace std;
      8 int n,m,l,ans[30001],lim;
      9 int father[10001];
     10 struct node{int from,to,dis;}map[50001];
     11 int find(int x){if(father[x]==x)return x;else return father[x]=find(father[x]);}
     12 bool cmp(const node a,const node b){return a.dis>b.dis;}
     13 struct question{int s,t,id;}que[60001];
     14 int head[10001],size=1;
     15 struct Node{int next,to,dis;}edge[100005];
     16 void putin(int from,int to,int dis){size++;edge[size].dis=dis;edge[size].to=to;edge[size].next=head[from];head[from]=size;}
     17 int fa[10001][15],mmin[10001][15],vis[10001],dep[10001];
     18 void dfs(int r,int depth)
     19 {
     20     vis[r]=1;
     21     dep[r]=depth;
     22     for(int i=head[r];i!=-1;i=edge[i].next)
     23     {
     24         int y=edge[i].to;
     25         if(!vis[y])
     26         {
     27             fa[y][0]=r;
     28             mmin[y][0]=edge[i].dis;
     29             dfs(y,depth+1);
     30         }
     31     }
     32 }
     33 void RMQ()
     34 {
     35     for(int i=1;i<=lim;i++)
     36         for(int j=1;j<=n;j++)
     37         {
     38             fa[j][i]=fa[fa[j][i-1]][i-1];
     39             mmin[j][i]=min(mmin[j][i-1],mmin[fa[j][i-1]][i-1]);
     40         }
     41 }
     42 int LCA(int x,int y)
     43 {
     44     int i,j,ans=2000000000;
     45     if(dep[x]<dep[y])swap(x,y);
     46     for(i=lim;i>=0;i--)
     47         if(dep[x]-(1<<i)>=dep[y])
     48         {
     49             ans=min(ans,mmin[x][i]);
     50             x=fa[x][i];
     51         }
     52     if(x!=y)
     53     {
     54         for(i=lim;i>=0;i--)
     55         {
     56             if(fa[x][i]!=fa[y][i])
     57             {
     58                 ans=min(ans,min(mmin[x][i],mmin[y][i]));
     59                 x=fa[x][i];
     60                 y=fa[y][i];
     61             }
     62         }
     63         ans=min(ans,min(mmin[x][0],mmin[y][0]));
     64         x=fa[x][0];
     65         y=fa[y][0];
     66     }
     67     return ans;
     68 }
     69 int main()
     70 {
     71     int i,j;
     72     memset(head,-1,sizeof(head));
     73     memset(ans,-1,sizeof(ans));
     74     memset(mmin,127/3,sizeof(mmin));
     75     scanf("%d%d",&n,&m);lim=log2(n);
     76     for(i=1; i<=n; i++)father[i]=i;
     77     for(i=1; i<=m; i++)scanf("%d%d%d",&map[i].from,&map[i].to,&map[i].dis);
     78     sort(map+1,map+m+1,cmp);
     79     for(i=1; i<=m; i++)
     80     {
     81         int p=find(map[i].from),q=find(map[i].to);
     82         if(p!=q)
     83         {
     84             father[p]=q;
     85             putin(p,q,map[i].dis);
     86             putin(q,p,map[i].dis);
     87         }
     88     }
     89     scanf("%d",&l);
     90     for(i=1;i<=n;i++)if(father[i]==i)dfs(i,0);
     91     RMQ();
     92     for(i=1; i<=l; i++)
     93     {
     94         int from,to;
     95         scanf("%d%d",&from,&to);
     96         if(find(from)==find(to))printf("%d
    ",LCA(from,to));
     97         else printf("-1
    ");
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    Windows配置深度学习环境详细教程(二):conda工具的使用
    Windows配置深度学习环境详细教程(一):安装Pycharm和Miniconda
    性能基准DevOps之如何提升脚本执行效率
    【Go语言绘图】图片添加文字(二)
    Cesium中用到的图形技术——Computing the horizon occlusion point
    Cesium中用到的图形技术——Horizon Culling
    Unity3D学习笔记3——Unity Shader的初步使用
    C++:异常处理
    mysql数据库备份
    编程小工具
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/7373415.html
Copyright © 2011-2022 走看看