码迷,mamicode.com
首页 > 其他好文 > 详细

P1967 货车运输 树链剖分

时间:2018-11-08 20:44:43      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:tom   cst   clu   can   一个   swap   ***   long   bit   

题目描述

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("******\n")
 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\n", qrange ( x, y ) );
165         else printf ( "-1\n" );
166     }
167     return 0;
168 }

 

P1967 货车运输 树链剖分

标签:tom   cst   clu   can   一个   swap   ***   long   bit   

原文地址:https://www.cnblogs.com/qldabiaoge/p/9931646.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!