NC50510. 皇宫看守
描述
输入描述
输入中数据描述一棵树,描述如下:
第一行n,表示树中结点的数目。
第二行至第n+1行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号,在该宫殿安置侍卫所需的经费k,该边的儿子数m,接下来m个数,分别是这个节点的m个儿子的标号。
对于一个n个结点的树,结点标号在1到n之间,且标号不重复。
输出描述
输出最少的经费
示例1
输入:
6 1 30 3 2 3 4 2 16 2 5 6 3 5 0 4 4 0 5 11 0 6 5 0
输出:
25
说明:
有六个区域被安排的情况如左图所示。C++(clang++ 11.0.1) 解法, 执行用时: 5ms, 内存消耗: 512K, 提交时间: 2023-07-30 23:03:14
#include<bits/stdc++.h> using namespace std; int k[1501],f[1501][3]; vector <int> g[1501]; void dfs(const int &u,const int &fa){ f[u][0] = k[u]; bool flag = 1; int x = INT_MAX; for (auto v : g[u]) if (v != fa){ dfs(v,u); f[u][0] += min(f[v][0],min(f[v][1],f[v][2])); f[u][1] += min(f[v][0],f[v][2]); if (f[v][0] <= f[v][2]){ f[u][2] += f[v][0]; flag = 0; }else{ f[u][2] += f[v][2]; x = min(x,f[v][0] - f[v][2]); } } if (flag)f[u][2] += x; } int main(){ int n,u,m,v,i; cin>>n; for (i = 0;i < n;i++){ cin>>u; cin>>k[u]>>m; while (m--){ cin>>v; g[u].push_back(v); g[v].push_back(u); } } dfs(1,0); cout<<min(f[1][0],f[1][2]); return 0; }