#include <map>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <functional>
#include <queue>
#include <deque>
#include <stack>
#include <cassert>
#include <iomanip>
#include <cmath>
#include <bitset>
using namespace std;
using int64 = long long;
struct Edge {
int x;
int y;
int w;
};
const int MAX_N = 1001;
int N, M;
vector<vector<int>> g;
vector<Edge> edges;
vector<int> par;
vector<int> child_idx;
vector<vector<Edge>> has_lca;
int dp_all[MAX_N];
int dp_minus[MAX_N][10];
int depth[MAX_N];
int bst[1<<10];
int dp[1<<10];
int buf[1<<10];
void dfs1(int v, int p) {
int idx = 0;
for (auto u : g[v]) if (u != p) {
depth[u] = depth[v] + 1;
child_idx[u] = idx++;
par[u] = v;
dfs1(u, v);
}
}
void dfs2(int v, int p) {
int idx = 0;
int nchild = 0;
vector<int> child;
for (auto u : g[v]) if (u != p) {
nchild++;
child.push_back(u);
dfs2(u, v);
}
memset(bst, 0, sizeof(bst));
memset(buf, 0, sizeof(buf));
auto best_cost = [&] (int x, int w, int & msk, int & cur) {
int last = -1;
cur += dp_all[x];
while (x != v) {
last = child_idx[x];
if (par[x] != v) {
cur += dp_minus[par[x]][last];
}
x = par[x];
}
msk |= (1<<last);
};
vector<int> cand;
for (auto e : has_lca[v]) {
int msk = 0;
int cur = e.w;
if (e.x != v) {
best_cost(e.x, e.w, msk, cur);
}
if (e.y != v) {
best_cost(e.y, e.w, msk, cur);
}
if (!bst[msk] && cur) {
cand.push_back(msk);
}
assert(msk);
bst[msk] = max(bst[msk], cur);
// cerr << (e.x+1) << " / " << (e.y+1) << " -> " << cur << "\n";
}
for (auto c : cand) {
for (int i = 0; i < nchild; i++) {
if (c >> i & 1) {
buf[c] += dp_all[child[i]];
}
}
}
for (int r = 0; r < nchild + 1; r++) {
memset(dp, 0, sizeof(dp));
for (int i = 0; i < nchild; i++) {
if (i == r) continue;
dp[0] += dp_all[child[i]];
}
if (r < nchild)
dp_minus[v][r] = dp[0];
dp_all[v] = max(dp_all[v], dp[0]);
for (int msk = 0; msk < (1<<nchild); msk++) {
for (auto c : cand) {
if ((msk & c) == c && !(c & (1<<r))) {
// cerr << "=> " << bst[c] << " " << buf[c] << "\n";
dp[msk] = max(dp[msk], dp[msk ^ c] + bst[c] - buf[c]);
if (r < nchild)
dp_minus[v][r] = max(dp_minus[v][r], dp[msk]);
dp_all[v] = max(dp_all[v], dp[msk]);
}
}
}
}
cerr << v+1 << " " << dp_all[v] << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cin >> N >> M;
g.resize(N);
has_lca.resize(N);
child_idx.assign(N, -1);
int tot = 0;
for (int i = 0; i < M; i++) {
int x, y, w;
cin >> x >> y >> w;
x--;
y--;
tot += w;
if (!w) {
g[x].push_back(y);
g[y].push_back(x);
} else {
edges.push_back(Edge{x, y, w});
}
}
par.assign(N, -1);
memset(depth, 0, sizeof(depth));
dfs1(0, 0);
for (auto e : edges) {
int x = e.x;
int y = e.y;
// cerr << depth[x] << " " << depth[y] << "\n";
if ((depth[x] & 1) != (depth[y] & 1))
continue;
while (depth[x] > depth[y]) {
x = par[x];
}
while (depth[y] > depth[x]) {
y = par[y];
}
while (x != y) {
x = par[x];
y = par[y];
}
has_lca[x].push_back(e);
cerr << (e.x+1) << ", " << (e.y+1) << " -> " << (x+1) << "\n";
}
dfs2(0, 0);
cout << tot - dp_all[0] << "\n";
return 0;
}
Compilation message
training.cpp: In function 'void dfs2(int, int)':
training.cpp:64:9: warning: unused variable 'idx' [-Wunused-variable]
64 | int idx = 0;
| ^~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
340 KB |
Output is correct |
2 |
Correct |
0 ms |
340 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
328 KB |
Output is correct |
2 |
Correct |
2 ms |
340 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
15 ms |
592 KB |
Output is correct |
2 |
Correct |
16 ms |
712 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
348 KB |
Output is correct |
2 |
Correct |
1 ms |
328 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
340 KB |
Output is correct |
2 |
Correct |
1 ms |
328 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
340 KB |
Output is correct |
2 |
Correct |
2 ms |
320 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
7 ms |
332 KB |
Output is correct |
2 |
Correct |
7 ms |
340 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
17 ms |
496 KB |
Output is correct |
2 |
Correct |
19 ms |
520 KB |
Output is correct |
3 |
Correct |
17 ms |
476 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
43 ms |
584 KB |
Output is correct |
2 |
Correct |
42 ms |
620 KB |
Output is correct |
3 |
Correct |
39 ms |
712 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
18 ms |
468 KB |
Output is correct |
2 |
Correct |
17 ms |
484 KB |
Output is correct |
3 |
Correct |
40 ms |
728 KB |
Output is correct |
4 |
Correct |
17 ms |
468 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
42 ms |
716 KB |
Output is correct |
2 |
Correct |
51 ms |
748 KB |
Output is correct |
3 |
Correct |
40 ms |
728 KB |
Output is correct |
4 |
Correct |
40 ms |
684 KB |
Output is correct |