zoukankan      html  css  js  c++  java
  • P1967 货车运输 树链剖分

    题目描述

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

    输入输出格式

    输入格式:

    第一行有两个用一个空格隔开的整数n,mn,m,表示 AA 国有nn 座城市和 mm 条道路。

    接下来 mm行每行33个整数 x, y, zx,y,z,每两个整数之间用一个空格隔开,表示从 xx号城市到yy号城市有一条限重为 zz 的道路。注意: xx 不等于 yy,两座城市之间可能有多条道路 。

    接下来一行有一个整数 q,表示有 q 辆货车需要运货。

    接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意: x 不等于 y 。

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    4 3
    1 2 4
    2 3 3
    3 1 1
    3
    1 3
    1 4
    1 3
    输出样例#1: 复制
    3
    -1
    3

    说明

    对于 30\%30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q< 1,0000<n<1,000,0<m<10,000,0<q<1,000;

    对于 60\%60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q< 1,0000<n<1,000,0<m<50,000,0<q<1,000;

    对于 100\%100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q< 30,000,0 ≤ z ≤ 100,0000<n<10,000,0<m<50,000,0<q<30,000,0z100,000。

    冷静思考  这就是求一个最大生成树  然后在这一颗树上面求路径最短

    然后我就被坑了   发现其实并不一定是联通总是不能全过

    后面加了这个才过的  

    for ( int i = 1 ; i <= n ; i++ ) {
           if ( id[i] ) continue;
           dfs1 ( i, 0, 1 );
           dfs2 ( i, i );
    }

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <set>
      7 #include <iostream>
      8 #include <map>
      9 #include <stack>
     10 #include <string>
     11 #include <vector>
     12 #define  pi acos(-1.0)
     13 #define  eps 1e-6
     14 #define  fi first
     15 #define  se second
     16 #define  lson l,mid,rt<<1
     17 #define  rson mid+1,r,rt<<1|1
     18 #define  rtl   rt<<1
     19 #define  rtr   rt<<1|1
     20 #define  mid   ((l+r)>>1)
     21 #define  bug         printf("******
    ")
     22 #define  mem(a,b)    memset(a,b,sizeof(a))
     23 #define  name2str(x) #x
     24 #define  fuck(x)     cout<<#x" = "<<x<<endl
     25 #define  f(a)        a*a
     26 #define  sf(n)       scanf("%d", &n)
     27 #define  sff(a,b)    scanf("%d %d", &a, &b)
     28 #define  sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
     29 #define  sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
     30 #define  pf          prLLf
     31 #define  FRE(i,a,b)  for(i = a; i <= b; i++)
     32 #define  FREE(i,a,b) for(i = a; i >= b; i--)
     33 #define  FRL(i,a,b)  for(i = a; i < b; i++)
     34 #define  FRLL(i,a,b) for(i = a; i > b; i--)
     35 #define  FIN         freopen("in.txt","r",stdin)
     36 #define  gcd(a,b)    __gcd(a,b)
     37 #define  lowbit(x)   x&-x
     38 #pragma comment(linker, "/STACK:1024000000,1024000000")
     39 using namespace std;
     40 typedef long long  LL;
     41 typedef unsigned long long ULL;
     42 const int mod = 1e9 + 7;
     43 const int maxn = 5e4;
     44 const int INF = 0x7fffffff;
     45 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
     46 int n, m, tot, head[maxn];
     47 int tree[maxn << 1], w1[maxn], rk[maxn];
     48 int son[maxn], id[maxn], fa[maxn], dep[maxn], sz[maxn], top[maxn], cnt;
     49 int father[maxn];
     50 struct Edge {
     51     int v, nxt, w;
     52 } edge[maxn];
     53 void init() {
     54     tot = cnt = 0;
     55     mem ( head, -1 );
     56     mem ( son, -1 );
     57 }
     58 void add ( int u, int v, int w ) {
     59     edge[tot].v = v;
     60     edge[tot].w = w;
     61     edge[tot].nxt = head[u];
     62     head[u] = tot++;
     63 }
     64 void dfs1 ( int u, int f, int deep ) {
     65     dep[u] = deep;
     66     fa[u] = f;
     67     sz[u] = 1;
     68     for ( int i = head[u]; ~i; i = edge[i].nxt ) {
     69         int v = edge[i].v;
     70         if ( v == f ) continue;
     71         w1[v] = edge[i].w;
     72         dfs1 ( v, u, deep + 1 );
     73         sz[u] += sz[v];
     74         if ( sz[son[u]] < sz[v] ) son[u] = v;
     75     }
     76 }
     77 void dfs2 ( int x, int topf ) {
     78     id[x] = ++cnt;
     79     rk[cnt] = x;
     80     top[x] = topf ;
     81     if ( son[x] == -1 ) return;
     82     dfs2 ( son[x], topf );
     83     for ( int i = head[x]; ~i; i = edge[i].nxt ) {
     84         int y = edge[i].v;
     85         if ( y == fa[x] || y == son[x] ) continue;
     86         dfs2 ( y, y );
     87     }
     88 }
     89 void build ( int l, int r, int rt ) {
     90     if ( l == r ) {
     91         tree[rt] = w1[rk[l]];
     92         return ;
     93     }
     94     build ( lson );
     95     build ( rson );
     96     tree[rt] = min ( tree[rtl], tree[rtr] );
     97 }
     98 int quary ( int L, int R, int l, int r, int rt ) {
     99     int ans = INF;
    100     if ( L <= l && r <= R ) return tree[rt];
    101     if ( L <= mid ) ans = min ( ans, quary ( L, R, lson ) );
    102     if ( R > mid )  ans = min ( ans, quary ( L, R, rson ) );
    103     return ans;
    104 }
    105 int qrange ( int x, int y ) {
    106     int ans = INF;
    107     while ( top[x] != top[y] ) {
    108         if ( dep[top[x]] < dep[top[y]] ) swap ( x, y );
    109         ans = min ( ans, quary ( id[top[x]], id[x], 1, n, 1 ) ) ;
    110         x = fa[top[x]];
    111     }
    112     if ( x != y ) {
    113         if ( dep[x] > dep[y] ) swap ( x, y );
    114         ans = min ( ans, quary ( id[x] + 1, id[y], 1, n, 1 ) ) ;
    115     }
    116     return ans ;
    117 }
    118 struct node {
    119     int u, v, w;
    120 } qu[maxn];
    121 int cmp ( node a, node b ) {
    122     return a.w > b.w;
    123 }
    124 int Find ( int x ) {
    125     return father[x] == x ? x : father[x] = Find ( father[x] );
    126 }
    127 int combine ( int x, int y ) {
    128     int nx = Find ( x ), ny = Find ( y );
    129     if ( nx != ny ) {
    130         father[ny] = nx;
    131         return 1;
    132     }
    133     return 0;
    134 }
    135 void krucal() {
    136     int k = 0;
    137     for ( int i = 0 ; i < m ; i++ ) {
    138         if ( combine ( qu[i].u, qu[i].v ) ) {
    139             k++;
    140             add ( qu[i].u, qu[i].v, qu[i].w );
    141             add ( qu[i].v, qu[i].u, qu[i].w );
    142             if ( k == n - 1 ) break;
    143         }
    144     }
    145 }
    146 int main() {
    147     scanf ( "%d%d", &n, &m );
    148     init();
    149     for ( int i = 0 ; i < m ; i++ ) scanf ( "%d%d%d", &qu[i].u, &qu[i].v, &qu[i].w );
    150     for ( int i = 0 ; i <= n ; i++  ) father[i] = i;
    151     sort ( qu, qu + m, cmp );
    152     krucal();
    153     for ( int i = 1 ; i <= n ; i++ ) {
    154         if ( id[i] ) continue;
    155         dfs1 ( i, 0, 1 );
    156         dfs2 ( i, i );
    157     }
    158     build ( 1, n, 1 );
    159     int q;
    160     scanf ( "%d", &q );
    161     while ( q-- ) {
    162         int x, y;
    163         scanf ( "%d%d", &x, &y );
    164         if ( Find ( x ) == Find ( y ) ) printf ( "%d
    ", qrange ( x, y ) );
    165         else printf ( "-1
    " );
    166     }
    167     return 0;
    168 }
  • 相关阅读:
    HDOJ 1207 汉诺塔II
    [转]写代码的小女孩
    POJ Subway tree systems
    HDOJ 3555 Bomb (数位DP)
    POJ 1636 Prison rearrangement (DP)
    POJ 1015 Jury Compromise (DP)
    UVA 10003
    UVA 103 Stacking Boxes
    HDOJ 3530 Subsequence
    第三百六十二、三天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/9931646.html
Copyright © 2011-2022 走看看