列表

详情


NC213878. CCA的图

描述

是不是经常向往外面的天空呢?那就来一场说走就走的旅行吧!
你现在在 s 号城市,想去 t 号城市,城市间有双向道路,保证任意两座城市可以通过这些道路相互到达。
但是出去的人太多了,以至于政府不得不给每条道路打上标记,这个标记是一个数字,政府会规定人们只能走标记在 [L , R] 内的道路。
现在你想求出在 L,R 分别等于多少时,你可以顺利到达 t 号城市,要求 L 尽可能大,在 L 最大的情况下 R 尽可能小 。 

输入描述

第一行四个正整数,n , m , s , t ,分别表示城市数量,道路数量和起点、终点城市编号 。
接下来的 m 行,每行三个正整数 u , v , w ,表示有一条连接 u,v 的双向道路,其标记为 w 。

输出描述

一行,两个正整数,表示最大的 L 和 在 L 最大的情况下最小的 R 。

示例1

输入:

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

输出:

2 3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 1414ms, 内存消耗: 38272K, 提交时间: 2020-12-21 19:56:11

#include<bits/stdc++.h>
using namespace std;
struct E{
	int a,b,id;
	friend bool operator < (E a,E b){
		return a.id<b.id;
	}
}e[3000005];
int n,m,fa[1000005],s,t;
void init(){
	for(int i=1;i<=n;i++)fa[i]=i;
}
int find(int x){
	if(fa[x]==x)return x;
	return fa[x]=find(fa[x]);
}
void uni(int a,int b){
	a=find(a),b=find(b);
	fa[a]=b;
}
int main(){
	scanf("%d%d%d%d",&n,&m,&s,&t);
	
	for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].id);
	int l,r;
	sort(e+1,e+m+1);
	init();
	for(int i=m;i>0;i--){
		uni(e[i].a,e[i].b);
		if(find(s)==find(t)){
			l=i;
			break;
		}
	}
	init();
	for(int i=l;i<=m;i++){
		uni(e[i].a,e[i].b);
		if(find(s)==find(t)){
			r=i;
			break;
		}
	}
	printf("%d %d\n",e[l].id,e[r].id);
	return 0;
}

上一题