Topic Link: Click to open the link
Test instructions
A forward tree of a given n point
The n-1 line below gives the forward edge.
Ask:
Modify the direction of the smallest possible side, you can choose 2 starting point so that the two points BFS can traverse all points.
Ideas:
Enumerates an edge, divides the tree into two parts, and calculates the minimum cost for each of the two parts at a time.
Then it becomes a DP on a subtree.
A method for the minimum side direction that a tree needs to be modified:
First, it is easy to find out: Dp[i] represents a subtree with I as the root, with I as the beginning of the cost.
At this point, if Root is the starting point, the price is cost[root] = Dp[root], if you start with any point in the tree
The price is cost[u] = Dp[root] + (number of sides in the root->u direction)-(number of sides in the u->root direction)
So in order to get the smallest cost[i], it is necessary to make (root->u direction of the number of sides)-(u->root direction of the number of sides) the largest.
So maintain (root->u direction of the number of sides)-(u->root direction of the number of sides) of the maximum value, the smallest cost[i] = dp[root]-max;
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include < cmath>using namespace Std;const int N = 1e5 + 10;struct edge{int from, to, DIS, NEX;} Edge[n<<1];int Head[n], edgenum;void Add (int u, int v, int d) {Edge E = {u, V, D, head[u]};edge[edgenum] = E;head[u ] = edgenum++;} int dp[n];int N, mx;void dfs (int u, int fa, int val) {Dp[u] = 0;for (int i = head[u]; ~i; i = edge[i].nex) {int v = edge[i]. To;if (v = = FA) Continue;dfs (V, U, Val-edge[i].dis);DP [u] + = Dp[v] + (edge[i].dis!=1);} mx = max (mx, val);} int main () {while (CIN >> N) {if (n = = 1) {puts ("0"); continue;} Memset (Head,-1, sizeof head); edgenum = 0;for (int i = 1, u, v; i < n; i++) {scanf ("%d%d", &u, &v); Add (U, V, 1) ; Add (V, U,-1);} int ans = 1 << 30;for (int i = 0, u, v; i < edgenum; i + = 2) {u = edge[i].from; v = edge[i].to;mx =-(1<<30) ;d FS (U, V, 0), int tmp = Dp[u]-mx;mx =-(1<<30);d fs (V, u, 0), tmp + = dp[v]-Mx;ans = min (ans, tmp);} PrinTF ("%d\n", ans);} return 0;}
Codeforces 238C World Eater-Tree DP