QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#463590 | #8253. Very Important Edge | 36champ | TL | 0ms | 0kb | C++20 | 5.9kb | 2024-07-05 01:51:06 | 2024-07-05 01:51:06 |
Judging History
answer
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const ll INF = 1LL << 62;
int n, m;
class DSU{
public:
vector<int> parent, rnk;
DSU(int n) {
parent = vector<int>(n, 0);
rnk = parent;
for(int i=0; i<n; i++) make_set(i);
}
void log()
{
for(int x: parent) cout << x << " ";
cout << "\n";
}
void make_set(int v) {
parent[v] = v;
rnk[v] = 0;
}
int find_set(int v) {
if(v < 0) return v;
if (v == parent[v])
return v;
parent[v] = find_set(parent[v]);
return parent[v];
}
void union_sets(int a, int b) {
if(a<0 || b<0) return;
a = find_set(a);
b = find_set(b);
if (a != b) {
if (rnk[a] < rnk[b])
swap(a, b);
parent[b] = a;
if (rnk[a] == rnk[b])
{
rnk[a]++;
}
}
}
};
class segTree{
public:
vector<ll> t;
segTree(int n)
{
t = vector<ll>(4 * n, INF);
}
void build(vector<ll> &a, ll v, ll tl, ll tr) {
if (tl == tr) {
t[v] = a[tl];
} else {
ll tm = (tl + tr) / 2;
build(a, v*2, tl, tm);
build(a, v*2+1, tm+1, tr);
t[v] = t[v*2] + t[v*2+1];
}
}
ll min(ll v, ll tl, ll tr, ll l, ll r) {
if (l > r)
return INF;
if (l == tl && r == tr) {
return t[v];
}
ll tm = (tl + tr) / 2;
return std::min(min(v*2, tl, tm, l, std::min(r, tm))
, min(v*2+1, tm+1, tr, max(l, tm+1), r));
}
void update(ll v, ll tl, ll tr, ll pos, ll new_val) {
if (tl == tr) {
t[v] = new_val;
} else {
ll tm = (tl + tr) / 2;
if (pos <= tm)
update(v*2, tl, tm, pos, new_val);
else
update(v*2+1, tm+1, tr, pos, new_val);
t[v] = std::min(t[v*2], t[v*2+1]);
}
}
};
void dfs(int p, vector<vector<vector<ll>>> &adj, vector<vector<int>> &up, vector<int> &depth, vector<ll> &v)
{
for(vector<ll> edge: adj[p])
{
ll c = edge[0], val = edge[1];
if(c == up[p][0]) continue;
v[c] = val;
depth[c] = depth[p] + 1;
up[c][0] = p;
for(int i=1; i<=19; i++) up[c][i] = up[up[c][i-1]][i-1];
dfs(c, adj, up, depth, v);
}
}
int lca(vector<vector<int>> &up, int u, int v, int d_u, int d_v)
{
if(d_v < d_u)
{
swap(u, v);
swap(d_u, d_v);
}
cerr << "LCA " << u << " " << d_u << " " << v << " " << d_v << " -> ";
for(int i=19; i>=0; i--)
{
if(d_u + (1 << i) <= d_v)
{
v = up[v][i];
d_v -= 1 << i;
}
}
cerr << v << " " << d_v << " = ";
if(u == v) return u;
for(int i=19; i>=0; i--)
{
if(up[u][i] != up[v][i])
{
u = up[u][i];
v = up[v][i];
}
}
return up[u][0];
}
void dfs2(int p, int &pos, vector<vector<vector<ll>>> &adj, vector<vector<vector<ll>>> &adj2, vector<vector<int>> &up, vector<int> &left, vector<vector<int>> &del, vector<ll> &l, segTree &T, vector<int> &depth)
{
//cout << "DFS 2 : " << p << " " << pos << "\n";
left[p] = pos;
for(vector<ll> edge: adj[p])
{
ll c = edge[0], val = edge[1];
if(c == up[p][0]) continue;
dfs2(c, pos, adj, adj2, up, left, del, l, T, depth);
}
for(vector<ll> edge: adj2[p])
{
ll c = edge[0], val = edge[1];
T.update(1, 0, 2*m-2*n+1, pos, val);
ll x = lca(up, p, c, depth[p], depth[c]);
del[x].pb(pos);
cerr << x << "\n";
pos++;
}
for(int index: del[p])
{
T.update(1, 0, 2*m-2*n+1, index, INF);
}
for(ll x: T.t) cerr << x << " ";
cerr << "\n";
cerr << "FIND MIN " << left[p] << " " << pos - 1 << " = ";
l[p] = T.min(1, 0, 2*m-2*n+1, left[p], pos - 1);
cerr << l[p] << "\n";
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m;
vector<vector<ll>> edge(m, {0, 0, 0});
vector<vector<int>> up(n + 1, vector<int>(20, 0));
ll ans = 0;
for(int i=0; i<m; i++) cin >> edge[i][1] >> edge[i][2] >> edge[i][0];
sort(edge.begin(), edge.end());
vector<vector<vector<ll>>> adj(n + 1), adj2(n + 1);
DSU a(n + 1);
for(int i=0; i<m; i++)
{
int u = edge[i][1], v = edge[i][2], c = edge[i][0];
if(a.find_set(u) != a.find_set(v))
{
a.union_sets(u, v);
ans += c;
adj[u].pb({v, c});
adj[v].pb({u, c});
}
else
{
adj2[u].pb({v, c});
adj2[v].pb({u, c});
}
}
vector<int> depth(n + 1, 0);
vector<ll> val(n + 1);
dfs(1, adj, up, depth, val);
for(int i=1; i<=n; i++)
{
for(int j=0; j<20; j++) cerr << up[i][j] << " ";
cerr << "\n";
}
/*for(int x: depth) cout << x << " ";
cout << "\n";*/
segTree T(2*m - 2*n + 2);
vector<int> left(n + 1);
vector<ll> l(n + 1, INF);
vector<vector<int>> del(n+1);
int pos = 0;
dfs2(1, pos, adj, adj2, up, left, del, l, T, depth);
for(ll x: l) cerr << x << " ";
ll M = 0;
for(int i=2; i<=n; i++) M = max(M, l[i] - val[i]);
cout << ans + M;
}
/*
6 8
1 2 1
1 3 2
2 4 3
2 5 4
3 6 5
4 5 6
1 5 7
2 6 8
*/
詳細信息
Test #1:
score: 0
Time Limit Exceeded
input:
1000 499500 26 715 732723 850 918 507404 276 643 372190 67 702 972051 397 777 337003 178 185 863117 61 151 943008 83 581 731622 99 501 3260 301 588 948638 17 908 147104 193 480 94512 347 415 416562 519 912 627431 70 959 86892 333 573 757685 129 197 181261 224 636 259176 335 426 567962 193 339 70097 ...