[NOIP2013 提高组] 货车运输
题目背景
NOIP2013 提高组 D1T3
题目描述
A 国有 n n n 座城市,编号从 1 1 1 到 n n n,城市之间有 m m m 条双向道路。每一条道路对车辆都有重量限制,简称限重。
现在有 q q q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
输入格式
第一行有两个用一个空格隔开的整数 $ n,m$,表示 A 国有 $ n$ 座城市和 m m m 条道路。
接下来 m m m 行每行三个整数 x , y , z x, y, z x,y,z,每两个整数之间用一个空格隔开,表示从 $x $ 号城市到 $ y $ 号城市有一条限重为 z z z 的道路。
注意: x ≠ y x \neq y x=y,两座城市之间可能有多条道路 。
接下来一行有一个整数 q q q,表示有 q q q 辆货车需要运货。
接下来 q q q 行,每行两个整数 x , y x,y x,y,之间用一个空格隔开,表示一辆货车需要从 x x x 城市运输货物到 y y y 城市,保证 x ≠ y x \neq y x=y
输出格式
共有 q q q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。
如果货车不能到达目的地,输出 − 1 -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% 的数据, 1 ≤ n < 1000 1 \le n < 1000 1≤n<1000, 1 ≤ m < 10 , 000 1 \le m < 10,000 1≤m<10,000, 1 ≤ q < 1000 1\le q< 1000 1≤q<1000;
对于 60 % 60\% 60% 的数据, 1 ≤ n < 1000 1 \le n < 1000 1≤n<1000, 1 ≤ m < 5 × 1 0 4 1 \le m < 5\times 10^4 1≤m<5×104, 1 ≤ q < 1000 1 \le q< 1000 1≤q<1000;
对于 100 % 100\% 100% 的数据, 1 ≤ n < 1 0 4 1 \le n < 10^4 1≤n<104, 1 ≤ m < 5 × 1 0 4 1 \le m < 5\times 10^4 1≤m<5×104,$1 \le q< 3\times 10^4 $, 0 ≤ z ≤ 1 0 5 0 \le z \le 10^5 0≤z≤105。
整体思路
因为最后所要输出的答案是每一辆货车的最大载重,那么假设这辆货车是在某一条道路上,那么这个最大载重便是从中间众多的道路上最大限重最小的一条,由此分析我们可得到这个背景下的核心问题:求两点之间所有路径的最小边长的最大值!!!
根据上述思路,可以考虑采用并查集的方法
具体见代码注释
涉及到的知识点
1.并查集2.树
完整代码
#include<bits/stdc++.h>
using namespace std;
int n,m,q;
set<int>::iterator it;
const int maxm = 50005;
const int maxn = 11111;
set<int> Q[11111];
struct edge{int u,v,cost;bool operator <(edge e1,edge e2){return e1.cost > e2.cost;}//重载运算符,更改排序优先级
}es[maxm];
int ans[maxm];
int parent[maxn];
int find(int x)
{ return x == parent[x]?x:parent[x] = find(parent[x]);
} //找根节点
int main(){memset(ans,-1,sizeof(ans));//初始化 for(int i = 1;i < maxn;++i)parent[i] = i;//将根节点首先初始化 scanf("%d%d",&n,&m);for(int i = 0;i < m;++i)scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].cost);sort(es,es+m);//排序 scanf("%d",&q);for(int i = 0;i < q;++i){int x,y;scanf("%d%d",&x,&y);Q[x].insert(i);Q[y].insert(i);//set插入元素无需插入 }for(int i = 0;i < m;++i){int x = es[i].u,y = es[i].v,c = es[i].cost;int px = find(x),py = find(y);if(px == py) continue;else{if(Q[px].size() > Q[py].size())swap(px,py);vector<int> tmp;for(it = Q[px].begin();it != Q[px].end();++it){int id = *it;if(Q[py].count(id))//set之后返回0和1 {ans[id] = c;tmp.push_back(id);}Q[py].insert(id);}for(int i = 0;i < tmp.size();++i)Q[py].erase(tmp[i]);parent[px] = py;}}for(int i = 0;i < q;++i)printf("%d\n",ans[i]);
}