This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct Guy {
int a;
int b;
int cost;
};
const int N = 1000 + 7;
const int INF = (int) 1e18;
const int B = 10;
vector<Guy> offers[N];
int sz[N];
int dp[N][1 << B];
int n;
int m;
vector<int> g[N];
int totalG;
int dep[N];
int parrent[N];
int getLca(int a, int b) {
while (a != b) {
assert(a >= 1);
assert(b >= 1);
if (dep[a] > dep[b]) {
a = parrent[a];
} else {
b = parrent[b];
}
}
return a;
}
void build(int a, int p = -1) {
vector<int> relege;
parrent[a] = p;
for (auto &b : g[a]) {
if (b == p) {
continue;
}
dep[b] = 1 + dep[a];
relege.push_back(b);
build(b, a);
}
g[a] = relege;
}
int who[N];
int skip[N];
void dfs(int a) {
for (auto &b : g[a]) {
dfs(b);
}
for (auto &it : offers[a]) {
vector<int> pathX, pathY;
int C = it.cost;
{
int X = it.a, Y = it.b;
while (X != a) {
assert(X >= 1);
pathX.push_back(X);
X = parrent[X];
}
while (Y != a) {
assert(Y >= 1);
pathY.push_back(Y);
Y = parrent[Y];
}
reverse(pathX.begin(), pathX.end());
reverse(pathY.begin(), pathY.end());
}
{
skip[a] = 0;
for (auto &it : pathX) skip[it] = 0;
for (auto &it : pathY) skip[it] = 0;
}
if (!pathX.empty()) skip[a] += (1 << who[pathX[0]]);
if (!pathY.empty()) skip[a] += (1 << who[pathY[0]]);
for (int j = 0; j + 1 < (int) pathX.size(); j++) skip[pathX[j]] += (1 << who[pathX[j + 1]]);
for (int j = 0; j + 1 < (int) pathY.size(); j++) skip[pathY[j]] += (1 << who[pathY[j + 1]]);
int current = C;
for (auto &it : pathX) current += dp[it][(1 << sz[it]) - 1 - skip[it]];
for (auto &it : pathY) current += dp[it][(1 << sz[it]) - 1 - skip[it]];
dp[a][skip[a]] = max(dp[a][skip[a]], current);
}
for (int mask = 0; mask < (1 << sz[a]); mask++) {
for (int sub = mask; sub; sub = (sub - 1) & mask) {
dp[a][mask] = max(dp[a][mask], dp[a][sub] + dp[a][mask ^ sub]);
}
int mx = 0;
for (int it = 0; it < sz[a]; it++) {
if (mask & (1 << it)) {
mx += dp[g[a][it]][(1 << sz[g[a][it]]) - 1];
}
}
dp[a][mask] = max(dp[a][mask], mx);
}
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0);
/// freopen ("input", "r", stdin);
cin >> n >> m;
vector<Guy> guys;
for (int i = 1; i <= m; i++) {
int a, b, c;
cin >> a >> b >> c;
if (!c) {
totalG++;
g[a].push_back(b);
g[b].push_back(a);
} else {
guys.push_back({a, b, c});
}
}
assert(totalG == n - 1);
build(1);
for (int i = 1; i <= n; i++) {
sz[i] = (int) g[i].size();
for (int j = 0; j < (int) g[i].size(); j++) {
who[g[i][j]] = j;
}
}
int needToPay = 0, totalSm = 0;
for (auto &it : guys) {
int a = it.a;
int b = it.b;
int cost = it.cost;
if (dep[a] % 2 != dep[b] % 2) {
needToPay += cost;
} else {
int lca = getLca(a, b);
offers[lca].push_back(it);
totalSm += cost;
}
}
dfs(1);
cout << needToPay + (totalSm - dp[1][(1 << sz[1]) - 1]) << "\n";
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |