CF1184E1

题目大意:

给出\(n\)个点\(m\)条边的无向图,你可以修改第一条边的权值,使得他可能会处于一棵最小生成树中,问你第一条的权值最大(不超过1e9)可以改为多少。

这个题我们不去使用第一条边去跑最小生成树,然后在跑的过程中,有一条边连接的两个联通分量与第一条连接是一样的,那么答案就是这条边的权值

如果最后没办法联通,说明第一条边是割边,答案是1e9。

#define B cout << "BreakPoint" << endl;
#define O(x) cout << #x << " " << x << endl;
#define O_(x) cout << #x << " " << x << " ";
#define Msz(x) cout << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#define fi first
#define se second
#define LL long long
const int inf = 1e9 + 9;
const int N = 2e6 + 5;
using namespace std;
inline int read() {
	int s = 0,w = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9') {
		if(ch == '-')
			w = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9') {
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	return s * w;
}
int fa[N];
int find(int x){
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}
vector<pair<int,pair<int,int> > > e(N);
int main(){
    int n = read(),m = read();
    for(int i = 0;i < m;i++){
        e[i].se.fi = read();
		e[i].se.se = read();
		e[i].fi = read();
    }  
    sort(e.begin() + 1,e.end());
    for(int i = 1;i <= n + 5;i++) fa[i] = i;
    for(int i = 1;i < e.size();i++){
        int u = find(e[i].se.fi),v = find(e[i].se.se);
        if(u != v){
            int x = find(e[0].se.fi),y = find(e[0].se.se);
            if(x == u && y == v) printf("%d\n",e[i].fi),exit(0);
            if(x == v && y == u) printf("%d\n",e[i].fi),exit(0);
            fa[u] = v;
        }
    }
    printf("%d\n",(int)1e9);
}
posted @ 2020-03-22 21:13  优秀的渣渣禹  阅读(132)  评论(0编辑  收藏  举报