 /**//*
Note that no country is under domination of more than one country, and the domination relationship makes no cycle.
给出一棵树,每个点有代价,选了父亲就能选中所有儿子,求最小的代价选中至少m个以上的点
直接tree dp +背包
但是注意不要重复算!选了父亲就相当于所有儿子都选了,就不能在这个基础上枚举儿子来更新!
*/
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include <sstream>
#include<algorithm>
#include<map>
using namespace std;

const int MAXN=210;
const int INF=1000000000;

vector<int>G[MAXN];
int dp[MAXN][MAXN];
int cost[MAXN],in[MAXN];
bool vi[MAXN];
int n,m;

 int dfs(int u) {
vi[u]=1;
int num=1;
 for(int i=0;i<G[u].size();i++) {
int v=G[u][i];
if(vi[v])continue;
num+=dfs(v);
}
for(int j=0;j<=n;j++)dp[u][j]=INF;
dp[u][0]=0;
 for(int i=0;i<G[u].size();i++) {
int v=G[u][i];
 for(int j=n;j;j--) {
for(int k=1;j-k>=0;k++)
if(dp[u][j]>dp[u][j-k]+dp[v][k])
dp[u][j]=dp[u][j-k]+dp[v][k];
}
}
//不要放在上面,因为num包括了所有儿子节点,然后还更新的话,就是重复了!
if(dp[u][num]>cost[u])dp[u][num]=cost[u];
return num;
}
 int main() {
char str[1000];
 while(gets(str)) {
if(str[0]=='#')break;
sscanf(str,"%d%d",&n,&m);
for(int i=0;i<=n;i++)G[i].clear();
map<string,int>Map;
memset(in,0,sizeof(in));
int ID=0;
 for(int i=1;i<=n;i++) {
scanf("%s",str);
if(Map.find(str)==Map.end())Map[str]=++ID;
int u=Map[str];
scanf("%d",&cost[u]);
//while(getchar()==' '){//因为只有空格!
// scanf("%s",str);
// if(Map.find(str)==Map.end())Map[str]=++ID;
// G[u].push_back(Map[str]);
// in[Map[str]]++;
//}
gets(str);
stringstream ss(str);
string name;
 while(ss>>name) {
if(Map.find(name)==Map.end())Map[name]=++ID;
G[u].push_back(Map[name]);
in[Map[name]]++;
}
}
cost[0]=INF;
 for(int i=1;i<=n;i++) {
if(in[i])continue;
G[0].push_back(i);
}
memset(vi,0,sizeof(vi));
dfs(0);
int ans=INF;
for(int j=m;j<=n;j++)
if(dp[0][j]!=-1&&dp[0][j]<ans)ans=dp[0][j];
printf("%d\n",ans);
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|