题目描述

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

输入输出格式

输入格式:

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

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

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

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

输出格式:

共有 qqq 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出−1-1−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%30\%30%的数据,0<n<1,000,0<m<10,000,0<q<1,0000 < n < 1,000,0 < m < 10,000,0 < q< 1,0000<n<1,000,0<m<10,000,0<q<1,000;

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

对于 100%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,0 ≤ z ≤ 100,0000<n<10,000,0<m<50,000,0<q<30,000,0≤z≤100,000。

题解:哦,这题是多么睿智啊,未来又可以多出一段梗了

有一回对我说道,“你学过OI吗么?”我略略点一点头。他说,“学过OI,……我便考你一考。2013年提高组的D1T3,怎样写的?”

我想,讨饭一样的人,也配考我么?便回过脸去,不再理会。

孔乙己等了许久,很恳切的说道,“不能写罢?……我教给你,记着!这些题应该记着。将来打比赛的时候,贺题要用。”

我暗想我和打模拟赛的水平还很远呢,而且我们比赛也从不将原题上账;又好笑,又不耐烦,懒懒的答他道,“谁要你教,不是最大生成树上跑跑倍增嘛?”

孔乙己显出极高兴的样子,将两个指头的长指甲敲着键盘,点头说,“对呀对呀!……这道题有四样写法,你知道么?”

我愈不耐烦了,努着嘴走远。孔乙己刚解了锁屏,想在电脑上写题,见我毫不热心,便又叹一口气,显出极惋惜的样子。

反正原来的做法就是最大生成树上跑跑lca,过程中顺便记录一下答案(lca至少有四种求法,不接受任何反驳╭(╯^╰)╮)

但我仔细一思索这题好像克鲁斯卡尔重构树也能做,大概做法就是建出一颗重构树以后输出询问两点之间的lca就可以啦

代码如下:

#include<bits/stdc++.h>
using namespace std; vector<int> g[];
struct edge
{
int from,to,val;
}e[];
int fa[],n,m,cnt,v[],deep[],f[][]; int cmp(edge x,edge y)
{
return x.val>y.val;
} int init()
{
for(int i=;i<=;i++)
{
fa[i]=i;
}
} int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
} int union_(int x,int y,int val)
{
int fx=find(x);
int fy=find(y);
if(fx==fy) return ;
fa[fx]=fa[fy]=++cnt;
g[fx].push_back(cnt);
g[cnt].push_back(fx);
g[fy].push_back(cnt);
g[cnt].push_back(fy);
v[cnt]=val;
} int dfs(int now,int fat,int dep)
{
f[now][]=fat;
deep[now]=dep;
for(int i=;i<=;i++) f[now][i]=f[f[now][i-]][i-];
for(int i=;i<g[now].size();i++)
{
if(g[now][i]==fat) continue;
dfs(g[now][i],now,dep+);
}
} int lca(int x,int y)
{
if(deep[x]<deep[y]) swap(x,y);
for(int i=;i>=;i--) if(deep[f[x][i]]>=deep[y]) x=f[x][i];
if(x==y) return x;
for(int i=;i>=;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][];
} int main()
{
init();
int from,to;
scanf("%d%d",&n,&m);
cnt=n;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].val);
}
sort(e+,e+m+,cmp);
for(int i=;i<=m;i++)
{
union_(e[i].from,e[i].to,e[i].val);
}
for(int i=;i<=cnt;i++)
{
if(find(i)==i) dfs(i,,);
}
int ttt;
scanf("%d",&ttt);
while(ttt--)
{
scanf("%d%d",&from,&to);
int anc=lca(from,to);
if(anc) printf("%d\n",v[anc]);
else puts("-1");
}
}

洛谷 P1967 货车运输(克鲁斯卡尔重构树)的更多相关文章

  1. NOIP 2013 提高组 洛谷P1967 货车运输 (Kruskal重构树)

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

  2. 2018.07.22 洛谷P1967 货车运输(kruskal重构树)

    传送门 这道题以前只会树剖和最小生成树+倍增. 而现在学习了一个叫做kruskal" role="presentation" style="position: ...

  3. 洛谷p1967货车运输(kruskal重构树)

    题面 题解中有很多说最优解是kruskal重构树 所以 抽了个早自习看了看这方面的内容 我看的博客 感觉真的挺好使的 首先对于kruskal算法来说 是基于贪心的思想把边权排序用并查集维护是否是在同一 ...

  4. 洛谷 P1967 货车运输

    洛谷 P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在 ...

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

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

  6. 【杂题总汇】NOIP2013(洛谷P1967) 货车运输

    [洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...

  7. 洛谷 P1967 货车运输 Label: 倍增LCA && 最小瓶颈路

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

  8. 洛谷P1967 货车运输

    题目描述 \(A\)国有\(n\)座城市,编号从\(1\)到\(n\),城市之间有\(m\)条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有\(q\)辆货车在运输货物, 司机们想知道每辆车在 ...

  9. [NOIP2013] 提高组 洛谷P1967 货车运输

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

随机推荐

  1. MFC vs. SDK程序流程

    大家都知道,windows API编程以及其消息处理,其过程都清晰可见,大体步骤如下: 1)声明消息窗口类 2)注册窗口类 3)createwindows 4)消息获得以及分派(windows pro ...

  2. php删除制定文件及文件夹

    php遍历一个文件夹内的所有文件和文件夹,并删除所有文件夹和子文件夹下的所有文件的代码,通过递归方式实现达到清空一个目录的效果,代码简单实用. 用到的函数: scandir($path) 遍历一个文件 ...

  3. Controlling DNS prefetching

    Controlling DNS prefetching IN THIS ARTICLE Background Configuring prefetching in the browser Contro ...

  4. DP系列——树形DP(Codeforces543D-Road Improvement)

    一.题目链接 http://codeforces.com/problemset/problem/543/D 二.题意 给一棵树,一开始所有路都是坏的.询问,以每个节点$i$为树根,要求从树根节点到其他 ...

  5. asp.net webapi 自托管插件式服务

    webapi问世已久,稀里糊涂的人哪它都当mvc来使,毕竟已mvc使用级别的经验就可以应对webapi. webapi和mvc在asp.net5时代合体了,这告诉我们,其实 它俩还是有区别的,要不现在 ...

  6. 535. Encode and Decode TinyURL

    ▶ 要求给出一种对 URL 网址进行压缩和解压的算法,例如 https://leetcode.com/problems/design-tinyurl ←→ http://tinyurl.com/4e9 ...

  7. C++中构造函数作用

    一. 构造函数是干什么的 class Counter { public: // 类Counter的构造函数 // 特点:以类名作为函数名,无返回类型 Counter() { m_value = ; } ...

  8. 我的Linux之路——windows10用WMware安装CentOS7.5 虚拟机详细步骤

    出自:https://www.jianshu.com/p/99f784d465f4 VMware简介:   VMware是一个虚拟PC的软件,可以在现有的操纵系统上虚拟出一个新的硬件环境,相当于模拟出 ...

  9. docker redis

    https://www.cnblogs.com/cgpei/p/7151612.html 重启docker >systmctl restart docker >mkdir -p ~/red ...

  10. Java里的堆(heap)栈(stack)和方法区(method)

    基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收.   引用数据类型,需要用new来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量 . 方法 ...