3287 货车运输

2013年NOIP全国联赛提高组

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
题目描述 Description

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

输入描述 Input Description

第一行有两个用一个空格隔开的整数 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 Description

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

样例输入 Sample Input

4 3 
1 2 4 
2 3 3 
3 1 1 
3
1 3 
1 4 
1 3

样例输出 Sample Output

3
-1
3

数据范围及提示 Data Size & 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。

/*
先跑最小生成树找到那些尽量大的边,
然后LCA维护两点间最小载重就好了。
至于-1的情况嘛 如果建完图后不在图里的自然就到不了了
怎么算是不在图里呢 深度为0且不是树根(1)。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define maxn 1000000 using namespace std;
int n,m,q,x,y,num,cnt,a,b,c,k,tmp;
int deep[maxn],head[maxn],fa[maxn];
int f[][],dis[][];
struct node
{
int from;
int to;
int dis;
int next;
};
node e[maxn*],p[maxn*]; void add(int from,int to,int dis)
{
e[++num].from=from;
e[num].to=to;
e[num].dis=dis;
e[num].next=head[from];
head[from]=num;
} bool cmp(node x,node y)
{
return x.dis>y.dis;
} int find(int x)
{
if(x==fa[x])return x;
else return fa[x]=find(fa[x]);
} void Kruskal()
{
for(int i=;i<=n;i++)
fa[i]=i;
sort(p+,p+m+,cmp);
for(int i=;i<=m;i++)
{
int r1=find(p[i].from);
int r2=find(p[i].to);
if(r1!=r2)
{
fa[r2]=r1;
add(p[i].from,p[i].to,p[i].dis);
add(p[i].to,p[i].from,p[i].dis);
k++;
}
if(k==n-) break;
}
} void DFS(int now,int from,int c,int Dis)
{
f[now][]=from;deep[now]=c;
dis[now][]=Dis;
for(int i=head[now];i;i=e[i].next)
{
if(e[i].to!=from)
DFS(e[i].to,now,c+,e[i].dis);
}
} void get_fa()
{
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
{
f[i][j]=f[f[i][j-]][j-];
dis[i][j]=min(dis[i][j],dis[f[i][j-]][j-]);
dis[i][j]=min(dis[i][j],dis[i][j-]);
}
} int get_same(int a,int t)
{
for(int i=;i<;i++)
{
if(t&(<<i))
{
tmp=min(tmp,dis[a][i]);
a=f[a][i];
}
}
return a;
} int LCA_query(int a,int b)
{
if(a!=&&deep[a]==) return -;
if(b!=&&deep[b]==) return -;
tmp=0x3f3f3f3f;
if(deep[a]<deep[b]) swap(a,b);
a=get_same(a,deep[a]-deep[b]);
if(a==b) return tmp;
else
{
for(int i=;i>=;i--)
{
if(f[a][i]!=f[b][i])
{
tmp=min(tmp,dis[a][i]);
tmp=min(tmp,dis[b][i]);
a=f[a][i];
b=f[b][i];
}
}
tmp=min(tmp,dis[a][]);
tmp=min(tmp,dis[b][]);
}
return tmp;
} int main()
{
memset(dis,/,sizeof dis);
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
p[i].from=a;
p[i].to=b;
p[i].dis=c;
}
Kruskal();
DFS(,,,);dis[][]=0x3f3f3f3f;
get_fa();
scanf("%d",&q);
for(int i=;i<=q;i++)
{
scanf("%d%d",&x,&y);
printf("%d\n",LCA_query(x,y));
}
return ;
}

codevs3287货车运输(最小生成树+LCA)的更多相关文章

  1. C++之路进阶——codevs3287(货车运输)

    3287 货车运输 2013年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description A 国有 n ...

  2. 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增

    倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...

  3. 【NOIP2013/Codevs3287】货车运输-最小生成树(大)-树上倍增

    https://www.luogu.org/problemnew/show/P1967 由题可知,我们走的路的边应尽可能大,所以通过kruscal建最大生成树的图,再树上倍增,注意可能有多棵树; #i ...

  4. P1967 货车运输[生成树+LCA]

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

  5. 货车运输(LCA+最大生成树)

    神奇传送门 恩,这是一道神奇的LCA+难度的题目. 题目是这样的: A 国有n座城市,编号从1到n,城市之间有 m条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q辆货车在运输货物,司机们 ...

  6. P1967 货车运输【LCA】【生成树】

    题目描述 A 国有 nn 座城市,编号从 11 到 nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重. 现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的 ...

  7. [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增

    Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...

  8. 【题解】洛谷P1967 [NOIP2013TG] 货车运输(LCA+kruscal重构树)

    洛谷P1967:https://www.luogu.org/problemnew/show/P1967 思路 感觉2013年D1T3并不是非常难 但是蒟蒻还是WA了一次 从题目描述中看出每个点之间有许 ...

  9. 洛谷P1967货车运输——倍增LCA

    题目:https://www.luogu.org/problemnew/show/P1967 就是倍增LCA的裸题,注意一些细节即可. 代码如下: #include<iostream> # ...

随机推荐

  1. 洛谷——P1073 最优贸易

    P1073 最优贸易 n 个城市间以 m 条有向道路连接, 小 T 从 1 号城市出发, 将要去往 n 号城市.小 T 观察到一款商品 Z 在不同的城市的价格可能不尽相同,小 T 想要在旅行中的某一个 ...

  2. iconfig1

    #include<iostream> using namespace std; //测试 template 里面是否还可以有 template class alloc{ }; templa ...

  3. Re0:DP学习之路 饭卡 HDU - 2546

    解法 01背包变式,首先贪心的想一下如果要保证余额最小那么就需要用相减后最小的钱减去之前最大的价格,且得保证这个钱在5元以上 对于寻找如何减最多能包含在5元以上,这里用01背包 我们把价钱看做体积装进 ...

  4. jieba的基本使用

    目录 1.分词 2.添加自定义词典 3.关键词提取 4.词性标注 jieba 是一款优秀的 Python 第三方中文分词库,可以使用 pip install jieba / pip3 install ...

  5. 原生js实现三个按钮绑定三个计时器,点击其中一个按钮,开启当前计时器,另外另个不开启

    今天在某个前端交流群,有个小伙伴问了一个小功能,自己想了一下,代码如下,可以实现基本功能: 下面是html结构 <div id="demo"> <input ty ...

  6. Leetcode 93.复制IP地址

    复制IP地址 给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式. 示例: 输入: "25525511135" 输出: ["255.255.11.135& ...

  7. [luoguP1156] 垃圾陷阱(DP)

    传送门 先按照时间排序 f[i][j] 表示 前i个物品高度为j时所剩余的最大能量 显然每个物品有堆和吃两种选择 状态转移看代码 代码 #include <cstdio> #include ...

  8. hdu poj KMP简单题目总结

    hdu 3336 题意:输入一个字符串求每个前缀在串中出现的次数和 sol:只要稍微理解下next 数组的含义就知道只要把每个有意义的next值得个数加起来即可 PS:网上有dp解法orz,dp[i] ...

  9. Quartz原理解密

    Quartz原理解密 Author: Dorae Date:2018年7月17日15:55:02 转载请注明出处 一.quartz概述 quartz是一个用java实现的开源任务调度框架,可以用来创建 ...

  10. java中static学习总结

    <<java编程思想>>: 1.static方法就是没有this的方法. 2.在static方法内部非静态方法. 3.在没有创建对象的前提下,可以通过类本身来调用static修 ...