标签:连通 dist int 题解 边权 201703 mid 号点
文章目录
题目解答
来源:acwing
分析:
题目给定n个点和m条边,要求最多选择n条边,使得1到n连通,然后每段路同时开工,求最小工时。换句话说,求的是连通路上最大边权最小。
这题可以用二分来做。为什么呢?
假设最大边权在数轴上的A点(边长为a)能够解决该题,那么换句话说,就是连通路径上,所有边长都是小于等于a。
作为题目,1到n点不会只有最佳的路径连通,还会有其他路径连通,只不过边权会大一点。也就是说,对于数轴上A点右边(长度都大于a),也是可以使得1到n连通的。而A点左边的点是不能使之连通的(否则的话,最优解就不是边长a啦)。
所以,满足这个性质(某个点的一边满足条件,而另一边不满足条件)的题目,可以用二分查找来枚举最优边权mid。
也就是说,对于枚举的边权mid,我们只走边权小于等于mid 的边,看是否1到n连通,并且走过的边数小于等于n。如果连通,说明枚举的mid大了,让r = mid;否则说明枚举的最优边权小了,应该让l = mid +1;
换个角度,构造两张图,一张是原图,另一张是边权为1的图,这样在遍历原图的边权小于mid时,说明这条路可以走,即在第二张图中可以选择这条路,我们在第二张图中求最短距离!这样做有什么好处呢?在第二张图中所有的边权都是1,然后bfs求最短路即可,只要到n号点的最短路小于等于n(在原图中的含义是走过了小于等于n条边),这就说明该mid是满足条件(连通,并且所选的边权都小于等于mid)的,可以让r= mid,遍历更小的mid,从而不断向最优解靠近,求出最优解。
ac代码
#include<bits/stdc++.h>
using namespace std;
const int N = 100010, M = 400010;
int n, m;
int h[N], e[M],w[M], ne[M], idx;
int dist[N];
int q[N];
void add(int a, int b, int c){
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
// 求1号点到n号点的最短路:边权为1
// 返回值为最短路,含义是:从1号点到n号点使用的边权小于等于mid 的条数
//如果 返回值 == 6,说明从1号点到n号点,使用边权小于等于mid的边的条数为6条
int bfs(int mid){
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
int hh = 0, tt = 0;
q[0] = 1;
while( hh <= tt){
int t = q[hh ++];
for(int i = h[t]; ~i; i = ne[i]){
if(w[i] > mid) continue;
int j = e[i];
if(dist[j] > dist[t] + 1){
dist[j] = dist[t] + 1;
q[++tt] = j;
}
}
}
return dist[n];
}
int main(){
cin >> n >> m;
memset(h, -1, sizeof h);
while(m --){
int a, b, c;
cin >> a >> b >> c;
add(a, b, c), add(b, a, c);
}
// 二分,枚举合适的最优边权
int l = 0, r = 1e6;
while(l < r){
int mid = l + r >> 1;
if(bfs(mid) <= n) r = mid;
else l = mid + 1;
}
//输出二分出来的分界点,二分退出时l == r
cout << r << endl;
}
题目链接
https://www.acwing.com/problem/content/description/3248/
标签:连通,dist,int,题解,边权,201703,mid,号点
来源: https://blog.csdn.net/shizheng_Li/article/details/115055029
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。