# Best Edge Weight

## 题目描述

You are given a connected weighted graph with $n$ vertices and $m$ edges. The graph doesn’t contain loops nor multiple edges. Consider some edge with id $i$. Let’s determine for this edge the maximum integer weight we can give to it so that it is contained in all minimum spanning trees of the graph if we don’t change the other weights.
You are to determine this maximum weight described above for each edge. You should calculate the answer for each edge independently, it means there can’t be two edges with changed weights at the same time.

## 代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct line {
long long u, v, c, id; bool mst;
bool operator < (const line &a) const { return c < a.c; }
} l[200001];
struct edge {
long long v, c, id, nxt;
} e[400001];
long long n, m, nume, h[200001], fa[200001], ans[200001];
long long depth[200001], up[200001][20], ma[200001][20], uid[200001];
long long get_fa(long long t) { return t == fa[t] ? t : fa[t] = get_fa(fa[t]); }
void add_edge(long long u, long long v, long long c, long long id) {
e[++nume].v = v, e[nume].c = c, e[nume].id = id, e[nume].nxt = h[u], h[u] = nume;
e[++nume].v = u, e[nume].c = c, e[nume].id = id, e[nume].nxt = h[v], h[v] = nume;
}
void dfs(long long t, long long fa) {
for (int i = h[t]; i; i = e[i].nxt)
if (e[i].v != fa) {
depth[e[i].v] = depth[t] + 1, up[e[i].v][0] = t;
ma[e[i].v][0] = e[i].c, uid[e[i].v] = e[i].id, dfs(e[i].v, t);
}
}
long long get_max(long long u, long long v) {
long long ret = 0;
if (depth[u] < depth[v]) u ^= v ^= u ^= v;
for (int i = 19; i >= 0; --i)
if (depth[u] - depth[v] >= (1 << i))
ret = max(ret, ma[u][i]), u = up[u][i];
if (u == v) return ret;
for (int i = 19; i >= 0; --i)
if (up[u][i] != up[v][i])
ret = max(ret, max(ma[u][i], ma[v][i])), u = up[u][i], v = up[v][i];
return max(ret, max(ma[u][0], ma[v][0]));
}
void update(long long u, long long v, long long val) {
if (depth[u] < depth[v]) u ^= v ^= u ^= v;
long long p = u, q = v;
for (int i = 19; i >= 0; --i)
if (depth[p] - depth[q] >= (1 << i)) p = up[p][i];
if (p != q) {
for (int i = 19; i >= 0; --i)
if (up[p][i] != up[q][i]) p = up[p][i], q = up[q][i];
p = up[p][0];
}
u = get_fa(u), v = get_fa(v);
while (depth[u] > depth[p])
ans[uid[u]] = val - 1, q = get_fa(up[u][0]), fa[u] = q, u = get_fa(u);
while (depth[v] > depth[p])
ans[uid[v]] = val - 1, q = get_fa(up[v][0]), fa[v] = q, v = get_fa(v);
}
int main()
{
cin >> n >> m, memset(ans, -1, sizeof ans);
if (n == m + 1) {
for (int i = 1; i <= m; cout << -1 << ' ', ++i); cout << endl; return 0;
}
for (int i = 1; i <= n; fa[i] = i, ++i);
for (int i = 1; i <= m; cin >> l[i].u >> l[i].v >> l[i].c, l[i].id = i, ++i);
sort(l + 1, l + m + 1);
for (int i = 1; i <= m; ++i) {
long long u = get_fa(l[i].u), v = get_fa(l[i].v);
if (u != v) add_edge(l[i].u, l[i].v, l[i].c, l[i].id), fa[u] = v, l[i].mst = true;
}
depth[1] = 1, dfs(1, 0);
for (int i = 1; i < 20; ++i)
for (int j = 1; j <= n; ++j) {
up[j][i] = up[up[j][i - 1]][i - 1];
ma[j][i] = max(ma[j][i - 1], ma[up[j][i - 1]][i - 1]);
}
for (int i = 1; i <= n; fa[i] = i, ++i);
for (int i = 1; i <= m; ++i)
if (!l[i].mst) {
ans[l[i].id] = get_max(l[i].u, l[i].v) - 1;
update(l[i].u, l[i].v, l[i].c);
}
for (int i = 1; i <= m; cout << ans[i] << ' ', ++i);
cout << endl;
return 0;
}


418 I'm a teapot