zoukankan      html  css  js  c++  java
  • NOIp 2013 Day1T3 货车运输

    Description

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

    Input:

    输入文件名为 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 。

    Output

    输出文件名为 truck.out。

    输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货

    车不能到达目的地,输出-1。

    Sample Input:

    4 3

    1 2 4

    2 3 3

    3 1 1

    3

    3

    1 4

    1 3


    Sample Output:

    3

    -1

    3


    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。


    方法一: 最大生成树 + 树上倍增,代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 const int maxn = 10000 + 5;
      8 const int maxm = 100000 + 5;
      9 struct Edge
     10 {
     11     int f, t, v;
     12     bool operator < (const Edge a) const
     13     {
     14         return v > a.v;
     15     }
     16 }gra[maxm], edg[maxm];
     17 int n, m, q, u;
     18 int fir[maxn], nxt[maxn << 1], fa[maxn];
     19 int dep[maxn], p[maxn][21], minn[maxn][21];
     20 bool used[maxn];
     21 void Build(int, int, int), Kruskal_hu(), DFS(int), Pre_lca();
     22 int Ask_lca(int, int), Ask_ans(int, int, int), Find(int);
     23 
     24 int main()
     25 {
     26     memset(fir, -1, sizeof(fir));
     27     memset(minn, 0x7f, sizeof(minn));
     28     scanf("%d%d", &n, &m);
     29     for(int i = 0; i < m; i++)
     30     {
     31         int f, t, v;
     32         scanf("%d%d%d", &f, &t, &v);
     33         edg[i] = (Edge){f, t, v};
     34     }
     35     Kruskal_hu();
     36     DFS(1);
     37     Pre_lca();
     38     scanf("%d", &q);
     39     while(q--)
     40     {
     41         int x, y;
     42         scanf("%d%d", &x, &y);
     43         if(Find(x) != Find(y)) puts("-1");
     44         else
     45         {
     46             int lca = Ask_lca(x, y);
     47             printf("%d
    ", Ask_ans(x, lca, y));
     48         }
     49     }
     50     return 0;
     51 }
     52 
     53 int Ask_ans(int x, int pa, int y)
     54 {
     55     int ans = 1e9 + 7;
     56     int f = dep[x] - dep[pa];
     57     for(int i = 20; i >= 0; i--)
     58         if((1 << i)&f)
     59         {
     60             ans = min(ans, minn[x][i]);
     61             x = p[x][i];
     62         }
     63     f = dep[y] - dep[pa];
     64     for(int i = 20; i >= 0; i--)
     65         if((1 << i)&f)
     66         {
     67             ans = min(ans, minn[y][i]);
     68             y = p[y][i];
     69         }
     70     return ans;
     71 }
     72 
     73 void Pre_lca()
     74 {
     75     for(int j = 1; (1 << j) <= n; j++)
     76         for(int i = 1; i <= n; i++)
     77         {
     78             p[i][j] = p[p[i][j - 1]][j - 1];
     79             minn[i][j] = min(minn[i][j - 1], minn[p[i][j - 1]][j - 1]);
     80         }
     81 }
     82 
     83 void DFS(int k)
     84 {
     85     used[k] = 1;
     86     for(int i = fir[k]; ~i; i = nxt[i])
     87     {
     88         int tmp = gra[i].t;
     89         if(used[tmp]) continue;
     90         p[tmp][0] = k;
     91         dep[tmp] = dep[k] + 1;
     92         minn[tmp][0] = gra[i].v;
     93         DFS(tmp);
     94     }
     95 }
     96 
     97 int Ask_lca(int x, int y)
     98 {
     99     if(dep[x] > dep[y]) swap(x, y);
    100     int f = dep[y] - dep[x];
    101     for(int i = 0; (1 << i) <= f; i++)
    102         if((1 << i)&f) y = p[y][i];
    103     if(x != y)
    104     {
    105         for(int i = 20; i >= 0; i--)
    106             if(p[x][i] != p[y][i])
    107             {
    108                 x = p[x][i];
    109                 y = p[y][i];
    110             }
    111         x = p[x][0];
    112     }
    113     return x;
    114 }
    115 
    116 void Build(int f, int t, int v)
    117 {
    118     gra[++u] = (Edge){f, t, v};
    119     nxt[u] = fir[f], fir[f] = u;
    120     gra[++u] = (Edge){t, f, v};
    121     nxt[u] = fir[t], fir[t] = u;
    122 }
    123 
    124 int Find(int x)
    125 {
    126     return fa[x] == x ? x : fa[x] = Find(fa[x]);
    127 }
    128 
    129 void Kruskal_hu()
    130 {
    131     for(int i = 1; i <= n; i++) fa[i] = i;
    132     sort(edg, edg + m);
    133     for(int i = 0; i < m; i++)
    134     {
    135         int x = Find(edg[i].f), y = Find(edg[i].t);
    136         if(x != y)
    137         {
    138             Build(edg[i].f, edg[i].t, edg[i].v);
    139             fa[x] = y;
    140         }
    141     }
    142 }
    MLT + LCA

    方法二:树链剖分 + 线段树,各种错误,弃坑

  • 相关阅读:
    十天学会php之第一天
    学习PHP的一些经验
    PHP中的数据类型(1)
    PHP中的常量
    赵凡导师并发知识第一次分享观后感
    面向对象之 __setitem__()、__getitem__()、__delitem__() 用法
    spider数据抓取(第二章)
    识别网站所用技术
    scrapy安装要求
    基于bs4的防止xss攻击,过滤script标签
  • 原文地址:https://www.cnblogs.com/DreifxP/p/7741134.html
Copyright © 2011-2022 走看看