Codeforces 219D Choosing Capital for Treeland 2次DP
//选择一个根使得变换最少边的方向使得能够到达所有点
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} const int MAXN = 200010; const int MAXM = MAXN * 10; struct Edge { int u,v,w; int next; }edge[MAXM]; int head[MAXN],tot; void init() { tot = 0; memset(head,-1,sizeof(head)); } void add_edge(int u,int v,int w) { edge[tot].u = u; edge[tot].v = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; } int dp[MAXN],f[MAXN]; void dfs1(int u,int pre) { dp[u] = 0; for (int i = head[u] ; i != -1 ; i = edge[i].next) { int v = edge[i].v; if (v == pre) continue; dfs1(v,u); dp[u] += dp[v] + edge[i].w; } } void dfs2(int u,int pre) { for (int i = head[u] ; i != -1 ; i = edge[i].next) { int v = edge[i].v,w = edge[i].w; if (v == pre) continue; f[v] = f[u] - w + (1 - w); dfs2(v,u); } } int main() { int N; while (cin >> N) { init(); for (int i = 0 ; i < N - 1 ; i++) { int u,v; scanf("%d%d",&u,&v); add_edge(u,v,0); add_edge(v,u,1); } dfs1(1,-1); f[1] = dp[1]; // cout << dp[1] << endl; dfs2(1,-1); int ans = N; for (int i = 1 ; i <= N ; i++) ans = min(ans,f[i]); cout << ans << endl; for (int i = 1 ; i <= N ; i++) if (f[i] == ans) printf("%d ",i); puts(""); } return 0; }
今年输的,明年全都要赢回来