Submission #1262712

#TimeUsernameProblemLanguageResultExecution timeMemory
1262712euclidTraining (IOI07_training)C++20
100 / 100
7 ms4932 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back #define fi first #define se second #define vi vector<int> #define pii pair<int, int> #define pll pair<ll, ll> #define vl vector<ll> struct edge { int u, v, c, l, x, y; //x, y: the indices of the two sons of l on the path from l to u, v }; int n, m, tot = 0; const int MN = 1007, MM = 5007, MS = (1<<10)+7; int dep[MN], fa[MN], jump[MN][11]; vi G[MN], g[MN]; vector<edge> b, a; vector<edge> e_lca[MN]; //e_lca[i]: all edges with l as the lca of its two endpoints int dp[MN][MS]; //dp[i][s]: for the subtree rooted at i, excluding all children nodes in s, //the maximum total cost we can get by adding edges into the graph int val[MN]; //val[v]: the precomputed value of sum of dps on a path from cur node to v vi order[11]; int bits(int x) {return __builtin_popcount(x);} void dfs(int node, int fat) { fa[node] = fat; dep[node] = dep[fat]+1; for(int child : g[node]) { if(child == fat) continue; G[node].pb(child); dfs(child, node); } } pii lca(int u, int v) { int j = 10; if(dep[v] > dep[u]) swap(u, v); for(int i = 0; i <= 10; i++) { if((1<<i)&(dep[u]-dep[v])) u = jump[u][i]; } if(u == v) return {u, u}; while(j >= 0) { if(jump[u][j] != jump[v][j]) { u = jump[u][j]; v = jump[v][j]; } j--; } return {u, v}; } void pushdown(int node, int fat, int v) { val[node] += v; for(int child : G[node]) { if(child == fat) continue; pushdown(child, node, v); } } void dfsdp(int node, int fat) { for(int child : G[node]) { if(child == fat) continue; dfsdp(child, node); } int sz = (int) G[node].size(); //not using any edges for(int s = 0; s < 1<<sz; s++) { for(int i = 0; i < sz; i++) { if(((1<<i)&s)==0) { dp[node][s] += dp[G[node][i]][0]; } } } //using some edge for(int s : order[sz]) { for(edge e : e_lca[node]) { // if(node == 1 && s == 0) { // cout << e.u << ' ' << e.v << ' ' << e.x << ' ' << e.y << '\n'; // } // if(node == 5) { // cout << e.u << ' ' << e.v << ' ' << e.x << ' ' << e.y << '\n'; // } if(e.x==-1 && e.y==-1) { //one of u, v is lca // cout << "here" << '\n'; int ind = -1; //find index of son on the path from u to v if(dep[e.u] < dep[e.v]) swap(e.u, e.v); for(int i = 0; i < sz; i++) { pii p = lca(e.u, G[node][i]); if(p.fi==p.se) ind = i; } if((1<<ind)&s) continue; dp[node][s] = max(dp[node][s], dp[node][s^(1<<ind)]+e.c+dp[e.u][0]+val[e.u]); } else { if((1<<e.x)&s || (1<<e.y)&s) continue; dp[node][s] = max(dp[node][s], dp[node][s^(1<<e.x)^(1<<e.y)]+val[e.u]+val[e.v]+ e.c+dp[e.u][0]+dp[e.v][0]); if(node == 1 && s == 0) { // cout << dp[node][s^(1<<e.x)^(1<<e.y)] << ' ' << val[e.u] << ' ' << val[e.v] << // ' ' << e.c << ' ' << dp[e.u][0] << ' ' << dp[e.v][0] << '\n'; // cout << "cur: " << dp[node][s] << '\n'; } } // if(s == 0 && node == 1 && dp[1][0] == 40) { // cout << "here: " << e.u << ' ' << e.v << '\n'; // } } } //precompute val for(int i = 0; i < sz; i++) { pushdown(G[node][i], node, dp[node][1<<i]); } } int cmp(int x, int y) { return bits(x) > bits(y); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m; for(int i = 1; i <= m; i++) { int x, y, z; cin >> x >> y >> z; if(z == 0) g[x].pb(y), g[y].pb(x); else b.pb({x, y, z, -1}); tot += z; } //lca precompute dfs(1, 1); for(int i = 1; i <= n; i++) jump[i][0] = fa[i]; for(int j = 1; j < 11; j++) { for(int i = 1; i <= n; i++) jump[i][j] = jump[jump[i][j-1]][j-1]; } for(edge e : b) { // remove all edges that directly form even cycles pii p = lca(e.u, e.v); if(p.fi==p.se) e.l = p.fi; else e.l = fa[p.fi]; // cout << e.u << ' ' << e.v << ' ' << e.l << '\n'; if((-2*dep[e.l]+dep[e.u]+dep[e.v]+1)%2==1) { if(p.fi==p.se) e.x=e.y=-1; for(int i = 0; i < G[e.l].size(); i++) { if(G[e.l][i] == p.fi) e.x = i; if(G[e.l][i] == p.se) e.y = i; // cout << i << '\n'; } a.pb(e); e_lca[e.l].pb(e); // cout << "pushed: " << e.u << ' ' << e.v << ' ' << e.x << ' ' << e.y << '\n'; } // cout << e.u << ' ' << e.v << '\n'; } //precompute order to iterate masks for(int sz = 1; sz <= 10; sz++) { for(int s = 0; s < 1<<sz; s++) order[sz].pb(s); sort(order[sz].begin(), order[sz].end(), cmp); } dfsdp(1, 0); cout << tot-dp[1][0] << '\n'; // cout << dp[1][0] << '\n'; // cout << lca(7, 11).fi << '\n'; // }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...