Question Analysis:
There are now n villages where you want to vote for you by buying M countries. The price for buying the I-th country is Val [I]. However, some countries have subordination. If B belongs to country A, buying a also means that B is bought, and these relations are transmitted. What is the minimum price you have to pay?
The difficulty of this question lies in how to build a map, which is not a weak dish. You can only worship the code of the great God, and then you may think about it yourself,The DFS part is similar to the general tree-like DP + backpack, but the state initialization changes somewhat.
Creating a graph requires a super root to connect a large country (a small country and a large country are subordinate)
DP [I] [J] indicates the minimum cost for obtaining a j ticket with I as the root.
Daniel usedMapToday, I read the basic knowledge of MAP and got up.
Paste the code of the hard-working AC. (I like A. I like adding C or V, but I don't like adding W in front)
# Include <iostream> # include <cstring> # include <cstdio> # include <string> # include <map> # include <vector> # include <set> # include <algorithm> # define INF 0x3f3f3f # define M 210 # define MS (S, i) memset (S, I, sizeof (s) using namespace STD; typedef Map <string, int> MSI; struct pp {int V, W, next ;} edge [M * 2]; int head [m], TOT, root, n, m; inline void addedge (int u, int V, int W, int * H) {edge [tot]. V = V, edge [tot]. W = W, edge [tot]. next = H [u], H [u] = tot ++;} int DP [210] [210], vis [210], W [210], Fa [210], num [210]; msi MP; void DFS (int u) {vis [u] = 1; DP [u] [0] = 0; num [u] = 1; // count how many sons are there at Father's Day for (INT I = head [u]; I! =-1; I = edge [I]. next) {int v = edge [I]. v; If (vis [v]) continue; DFS (V); num [u] + = num [v]; for (int K = num [u]; k> = 1; -- k) {// number of votes that the son can obtain for (Int J = 0; j <= K & J <= num [v]; ++ J) {// select the optimal DP [u] [k] = min (DP [u] [k] in the number of votes, DP [u] [k-J] + dp [v] [J]); // 01 backpack }}dp [u] [num [u] = W [u]; // return;} int main () {// freopen ("input.txt", "r", stdin); // freopen ("output.txt", "W", stdout); char s [1, 1000]; while (gets (s) {If (s [0] = '#') break; sscanf (S, "% d % D ", & N, & M); Tot = 0, MP. clear (), MS (DP, 0x3f), MS (VIS, 0), MS (FA, 0), MS (Head,-1), MS (Num, 0 ); int id = 0; For (INT I = 1; I <= N; ++ I) {scanf ("% s", S); If (MP. find (S) = MP. end () {MP [s] = ++ ID;} int u = MP [s]; scanf ("% d", & W [u]); while (getchar ()! = '\ N') {scanf ("% s", S); If (MP. find (S) = MP. end () {MP [s] = ++ ID;} addedge (u, MP [s], 0, head ); fa [MP [s] = 1 ;}}for (INT I = 1; I <= N; ++ I) {If (! Fa [I]) addedge (0, I, 0, head);} W [0] = 0; DFS (0); int ans = inf; for (INT I = m; I <= N; ++ I) {If (DP [0] [I] <ans) ans = DP [0] [I];} cout <ans <Endl;} return 0 ;}