(图论)汤圆防漏理论
题意
\(题目让我们找到一个最大值k,使得每删去一个点v,都使得删去点的边权和不超过k.\)
思路
\(容易想到一定是优先删去边权和最小的最好\)
\(所以这里要始终能找到一个最小边权之和的点,用set就很方便\)
\(我们先把所有点放入set,每次拿出边权和最小的点,用它去更新其他点的边权和\)
代码
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
inline int lowbit(int x) { return x & (-x); }
#define ll long long
#define ull unsigned long long
#define pb push_back
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define VIT vector<int>
#define x first
#define y second
#define inf 0x3f3f3f3f
const int N = 1e5 + 7, M = 2 * N;
bool st[N];
vector<PII> v[N];
ll sum[N];
set<pair<ll, int>> s;
int main() {
IO;
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int _;
cin >> _;
while (_--) {
s.clear();
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
st[i] = 0;
sum[i] = 0;
v[i].clear();
}
while (m--) {
int a, b, c;
cin >> a >> b >> c;
v[a].pb({b, c});
v[b].pb({a, c});
sum[a] += c;
sum[b] += c;
}
for (int i = 1; i <= n; ++i)
s.insert({sum[i], i});
ll ans = 0;
while (s.size()) {
auto t = s.begin();
s.erase(s.begin());
ans = max(ans, (*t).x);
int ver = (*t).y;
st[ver] = 1;
for (int i = 0; i < v[ver].size(); ++i) {
int j = v[ver][i].x;
if (st[j]) continue;
s.erase({sum[j], j});
sum[j] -= v[ver][i].y;
s.insert({sum[j], j});
}
}
cout << ans << '\n';
}
return 0;
}