CF1777E

Sol

很考验注意力啊。

注意限制是边权最大值,想到二分,对于能反向的边建双向边,否则建单向边,跑缩点后判断是否只有一个点没有入度,证明显然。

自己想出来的 *2200,很难得啊。

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define pf push_front
#define desktop "C:\\Users\\incra\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
	if (y > x) return x = y,true;
	return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
	if (y < x) return x = y,true;
	return false;
}
LL power (LL a,LL b,LL p) {
	LL ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 200010;
int n,m;
tuple <int,int,int> e[N];
vector <int> g[N];
int dfn[N],low[N],timestamp;
int stk[N];
int top;
bool in_stk[N];
int id[N],scc_cnt;
int in_deg[N];
void tarjan (int u) {
    dfn[u] = low[u] = ++timestamp;
    stk[++top] = u;
    in_stk[u] = 1;
    for (int v : g[u]) {
        if (!dfn[v]) {
            tarjan (v);
            tomin (low[u],low[v]);
        }
        else if (in_stk[v]) tomin (low[u],dfn[v]);
    }
    if (dfn[u] == low[u]) {
        int v;
        scc_cnt++;
        do {
            v = stk[top--];
            in_stk[v] = 0;
            id[v] = scc_cnt;
        }
        while (v != u) ;
    }
}
bool check (int lim) {
    for (int i = 1;i <= n;i++) g[i].clear (),dfn[i] = 0,in_deg[i] = 0;
    for (int i = 1;i <= m;i++) {
        int a,b,c;
        tie (a,b,c) = e[i];
        g[a].pb (b);
        if (c <= lim) g[b].pb (a);
    }
    timestamp = scc_cnt = 0;
    for (int i = 1;i <= n;i++) {
        if (!dfn[i]) tarjan (i);
    }
    // cout << lim << "    " << scc_cnt << ' ' << id[1] << ' ' << id[2] << endl;
    for (int i = 1;i <= n;i++) {
        for (int j : g[i]) {
            if (id[i] != id[j]) in_deg[id[j]]++;
        }
    }
    int cnt = 0;
    for (int i = 1;i <= scc_cnt;i++) cnt += !in_deg[i];
    return cnt == 1;
}
void mian () {
    cin >> n >> m;
    for (int i = 1;i <= m;i++) {
        int a,b,c;
        cin >> a >> b >> c;
        e[i] = {a,b,c};
    }
    int l = 0,r = 1e9;
    while (l < r) {
        int mid = l + r >> 1;
        if (check (mid)) r = mid;
        else l = mid + 1;
    }
    if (!check (l)) l = -1;
    cout << l << endl;
}
int main () {
	int T = 1;
	cin >> T;
	while (T--) mian ();
	return 0;
}
posted @ 2025-03-10 17:05  incra  阅读(7)  评论(0)    收藏  举报