zoukankan      html  css  js  c++  java
  • 洛谷P1967 [NOIP2013提高组Day1T2]货车运输

    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。

    【题解】

    最大生成树+树上倍增,证明可用反证法或者显然法(唔)

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #define min(a, b) ((a) < (b) ? (a) : (b))
      7 
      8 inline void read(int &x)
      9 {
     10     x = 0;char ch = getchar(), c = ch;
     11     while(ch < '0' || ch > '9') c = ch, ch = getchar();
     12     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
     13     if(c == '-') x = -x;
     14 }
     15 
     16 inline void swap(int &a, int &b)
     17 {
     18     int tmp = a;a = b;b = tmp;
     19 }
     20 
     21 const int MAXN = 10000 + 10;
     22 const int MAXM = 50000 + 10;
     23 const int INF = 0x3f3f3f3f;
     24 
     25 int n,m,u[MAXM],v[MAXM],w[MAXM],cnt[MAXM],q,s,t,fa[MAXN],b[MAXM];
     26 
     27 bool cmp(int a, int b)
     28 {
     29     return w[a] > w[b];
     30 }
     31 
     32 struct Edge
     33 {
     34     int u,v,w,next;
     35     Edge(int _u, int _v, int _w, int _next){u = _u, v = _v, w = _w, next = _next;}
     36     Edge(){}
     37 }edge[MAXN << 1];
     38 int head[MAXN], cntt;
     39 inline void insert(int a, int b, int c)
     40 {
     41     edge[++cntt] = Edge(a,b,c,head[a]);
     42     head[a] = cntt;
     43 }
     44 
     45 int deep[MAXN], p[20][MAXN], mi[20][MAXN];
     46 
     47 void dfs(int u)
     48 {
     49     b[u] = 1;
     50     for(register int pos = head[u];pos;pos = edge[pos].next)
     51     {
     52         int v = edge[pos].v;
     53         if(b[v])continue;
     54         deep[v] = deep[u] + 1;
     55         p[0][v] = u;
     56         mi[0][v] = edge[pos].w;
     57         dfs(v);
     58     }
     59 }
     60 
     61 void yuchuli()
     62 {
     63     int M = 0;
     64     while((1 << M) <= n) ++ M;
     65     -- M;
     66     for(register int i = 1;i <= M;++ i)
     67         for(register int j = 1;j <= n;++ j)
     68             p[i][j] = p[i - 1][p[i - 1][j]];
     69     for(register int i = 1;i <= M;++ i)
     70         for(register int j = 1;j <= n;++ j)
     71             mi[i][j] = min(mi[i - 1][p[i - 1][j]], mi[i - 1][j]);
     72 }
     73 
     74 int LCA(int va, int vb)
     75 {
     76     if(deep[va] < deep[vb]) swap(va, vb);
     77     int M = 0;
     78     while((1 << M) <= n)++ M;
     79     -- M;
     80     for(register int i = M;i >= 0;-- i)
     81         if(deep[vb] + (1 << i) <= deep[va])
     82             va = p[i][va];
     83     if(va == vb)return va;
     84     M = 0;
     85     while((1 << M) <= deep[va]) ++ M;
     86     -- M;
     87     for(register int i = M;i >= 0;-- i)
     88         if(p[i][va] != p[i][vb])
     89         {
     90             va = p[i][va];
     91             vb = p[i][vb];
     92         }
     93     return p[0][va];
     94 }
     95 
     96 int find(int x)
     97 {
     98     return x == fa[x] ? x : fa[x] = find(fa[x]);
     99 }
    100 
    101 int main()
    102 {
    103     read(n), read(m);
    104     for(register int i = 1;i <= m;++i)
    105         read(u[i]), read(v[i]), read(w[i]), cnt[i] = i;
    106     for(register int i = 1;i <= n;++ i)
    107         fa[i] = i;
    108     std::sort(cnt + 1, cnt + 1 + m, cmp);
    109     for(register int i = 1;i <= m;++i)
    110     {
    111         int f1 = find(u[cnt[i]]), f2 = find(v[cnt[i]]);
    112         if(f1 != f2)
    113         {
    114             fa[f1] = f2;
    115             insert(u[cnt[i]], v[cnt[i]], w[cnt[i]]);
    116             insert(v[cnt[i]], u[cnt[i]], w[cnt[i]]);
    117         }
    118     }
    119     for(register int i = 1;i <= n;++ i)
    120     {
    121         if(!b[i])
    122         {
    123             deep[i] = 1;
    124             dfs(i);
    125         }
    126     }
    127     yuchuli();
    128     read(q);
    129     int s,t;
    130     int M = 0;
    131     while((1 << M) <= n) ++ M;
    132     -- M;
    133     for(register int i = 1;i <= q;++ i)
    134     {
    135         read(s), read(t);
    136         int f1 = find(s), f2 = find(t);
    137         if(f1 != f2)
    138         {
    139             printf("-1
    ");
    140             continue;
    141         }
    142         int lca = LCA(s, t);
    143         int mi1 = INF, mi2 = INF;
    144         for(register int j = M;j >= 0;-- j)
    145             if(p[j][s] && deep[p[j][s]] >= deep[lca])
    146             {
    147                 mi1 = min(mi1, mi[j][s]);
    148                 s = p[j][s];
    149             }    
    150         for(register int j = M;j >= 0;-- j)
    151             if(p[j][t] && deep[p[j][t]] >= deep[lca])
    152             {
    153                 mi2 = min(mi2, mi[j][t]);
    154                 t = p[j][t];
    155             }
    156         printf("%d
    ", min(mi1, mi2));
    157     }
    158     return 0;
    159 }
    NOIP2013Day1T3
  • 相关阅读:
    ZTree id值太大,ZTree没有生成树,ZTree的id值过大
    Spring NamedParameterJdbcTemplate命名参数查询条件封装, NamedParameterJdbcTemplate查询封装
    Linux Redis 重启数据丢失解决方案,Linux重启后Redis数据丢失解决方
    Linux Redis自动启动,Redis开机启动,Linux Redis设置开机启动
    Linux Redis安装,Linux如何安装Redis,Linux Redis自动启动,Redis开机启动
    springJdbc in 查询,Spring namedParameterJdbcTemplate in查询
    Sublime的插件Color Highlighter的安装方法
    Sublime的Package Control安装方法
    JavaScript实现最简单的拖拽效果
    css抠图之background-position-背景定位
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7544761.html
Copyright © 2011-2022 走看看