当然还有最基本的限制,对某个节点 $u$ 以及某个礼物 $i$,$g_{1, i, 0} \rightarrow g_{1, i, 1}$(强制要求 $i$ 在 $1$ 的子树中)、$g_{u, i, 1} \rightarrow g_{fa_u, i, 1}$、$g_{u, i, 0} \rightarrow g_{son_u, i, 0}$、$g_{u, i, 1} \rightarrow g_{v, i, 0}$(其中 $u, v$ 的两个子树无交集)
structLFS {int to, next; } ; LFS Link[MAXL]; int Head[MAXK]= {0}, size = 0; voidInsert(int u, int v){ Link[++ size].to = v; Link[size].next = Head[u];
Head[u] = size; }
vector<int> G[MAXN]; int father[MAXN]= {0}, depth[MAXN]= {0}; voidDFS(int root, int fa){ father[root] = fa; for (int i = 0; i < (int) G[root].size(); i ++) { int v = G[root][i]; if (v == fa) continue; depth[v] = depth[root] + 1; DFS (v, root); } } boolisanc(int y, int x){ if (! x) returnfalse; return x == y ? true : isanc (y, father[x]); }
int N, M, Q; int g[MAXN][MAXN][2]= {0}, m = 0;
int dfn[MAXK]= {0}, low[MAXK]= {0}, ord = 0; intstack[MAXK]= {0}, top = 0; bool insta[MAXK]= {false}; int bel[MAXK]= {0}, co = 0; voidTarjan(int u){ dfn[u] = low[u] = ++ ord; stack[++ top] = u; insta[u] = true; for (int i = Head[u]; i; i = Link[i].next) { int v = Link[i].to; if (! dfn[v]) { Tarjan (v); low[u] = min (low[u], low[v]); } elseif (insta[v]) low[u] = min (low[u], dfn[v]); } if (dfn[u] == low[u]) { co ++; int x; do { x = stack[top --]; insta[x] = false, bel[x] = co; } while (x != u); } }
int ans[MAXN]= {0};
inlineintgetnum(){ int num = 0; char ch = getchar (); while (! isdigit (ch)) ch = getchar (); while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return num; }
intmain(){ N = getnum (), M = getnum (), Q = getnum (); for (int i = 1; i < N; i ++) { int u = getnum (), v = getnum (); G[u].push_back(v); G[v].push_back(u); } depth[1] = 1, DFS (1, 0); for (int i = 1; i <= N; i ++) for (int j = 1; j <= M; j ++) g[i][j][1] = ++ m, g[i][j][0] = ++ m; for (int i = 1; i <= Q; i ++) { int a = getnum (), b = getnum (), u = getnum (); if (father[u]) { Insert (g[u][a][0], g[u][b][1]); Insert (g[u][b][0], g[u][a][1]); } for (int j = 0; j < (int) G[u].size(); j ++) { int v = G[u][j]; if (v != father[u]) { Insert (g[v][a][1], g[v][b][0]); Insert (g[v][b][1], g[v][a][0]); } } } for (int i = 1; i <= N; i ++) for (int j = 1; j <= M; j ++) { if (father[i]) Insert (g[i][j][1], g[father[i]][j][1]); for (int k = 0; k < (int) G[i].size(); k ++) if (G[i][k] != father[i]) Insert (g[i][j][0], g[G[i][k]][j][0]); } for (int i = 1; i <= M; i ++) Insert (g[1][i][0], g[1][i][1]); for (int i = 1; i <= N; i ++) for (int j = 1; j <= N; j ++) if (! isanc (i, j) && ! isanc (j, i)) for (int k = 1; k <= M; k ++) Insert (g[i][k][1], g[j][k][0]); for (int i = 1; i <= m; i ++) if (! dfn[i]) Tarjan (i); for (int i = 1; i <= N; i ++) for (int j = 1; j <= M; j ++) if (bel[g[i][j][1]] < bel[g[i][j][0]]) ans[j] = depth[ans[j]] < depth[i] ? i : ans[j]; for (int i = 1; i <= M; i ++) { if (i > 1) putchar (' '); printf ("%d", ans[i]); } puts ("");
boolsolve(){ if (a[1] < a[N]) returnfalse; int l = K, r = K, ll = K, lr = K; for (int i = l; i >= 1; i --) if (a[i] >= a[ll]) ll = i; for (int i = r; i <= N; i ++) if (a[i] <= a[lr]) lr = i; while (l != ll || r != lr) { int pl, pr; bool suc = false; for (pl = l; pl > ll; ) { if (a[pl - 1] < a[r]) break; if (a[-- pl] >= a[l]) break; } if (pl < l && a[pl] >= a[l]) { l = pl; suc = true; } for (pr = r; pr < lr; ) { if (a[pr + 1] > a[l]) break; if (a[++ pr] <= a[r]) break; } if (pr > r && a[pr] <= a[r]) { r = pr; suc = true; } if (! suc) returnfalse; } l = 1, r = N; while (l != ll || r != lr) { int pl, pr; bool suc = false; for (pl = l; pl < ll; ) { if (a[pl + 1] < a[r]) break; if (a[++ pl] >= a[l]) break; } if (pl > l && a[pl] >= a[l]) { l = pl; suc = true; } for (pr = r; pr > lr; ) { if (a[pr - 1] > a[l]) break; if (a[-- pr] <= a[r]) break; } if (pr < r && a[pr] <= a[r]) { r = pr; suc = true; } if (! suc) returnfalse; } returntrue; }
inlineintgetnum(){ int num = 0; char ch = getchar (); bool isneg = false; while (! isdigit (ch)) { if (ch == '-') isneg = true; ch = getchar (); } while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return isneg ? - num : num; }
intmain(){ T = getnum (); for (int Case = 1; Case <= T; Case ++) { N = getnum (), K = getnum (); for (int i = 1; i <= N; i ++) a[i] = getnum (); for (int i = 2; i <= N; i ++) a[i] += a[i - 1]; solve () ? puts ("Yes") : puts ("No"); }