题意:有n个国家,贿赂它们都需要一定的代价,一个国家被贿赂了从属这个国家的国家也相当于被贿赂了,问贿赂至少k个国家的最少代价。

这些国家的从属关系形成一个森林,加个超级根连接,就是一棵树了,考虑用DP:

  • dp[u][m]表示以u国家为根的子树贿赂m个国家的最少代价

单单这样的话转移是指数级的,其实这题就是树上背包,同HDU1516。现在觉得想明白了,其实就是所有结点为根做n次01背包,每次01背包的物品就是当前根的各个儿子。

状态加一维度表示,转移就可以不是指数级了:

  • dp[u][n][m]表示以u国家为根的前n个儿子构成的子树贿赂m个国家的最少代价

然后其实循环利用内存,像01背包一样省去一维背包从大到小枚举,然后就是那样了。。

 #include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
#define INF (1<<29)
#define MAXN 222 struct Edge{
int u,v,next;
}edge[MAXN];
int NE,head[MAXN];
void addEdge(int u,int v){
edge[NE].u=u; edge[NE].v=v; edge[NE].next=head[u];
head[u]=NE++;
} int n,k,cost[MAXN],d[MAXN][MAXN],size[MAXN];
void getsize(int u){
size[u]=;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
getsize(v);
size[u]+=size[v];
}
}
void dfs(int u){
if(u) d[u][size[u]]=cost[u];
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
dfs(v);
for(int j=size[u]; j>=; --j){
for(int k=; k<j; ++k) d[u][j]=min(d[u][j],d[u][k]+d[v][j-k]);
}
}
} bool read(char *&s,int &t){
if(sscanf(s,"%d",&t)!=) return ;
while(*s==' ') ++s;
while(*s>='' && *s<='') ++s;
while(*s==' ') ++s;
return ;
}
bool read(char *&s,char *str){
if(sscanf(s,"%s",str)!=) return ;
while(*s==' ') ++s;
while(*s && *s!=' ') ++s;
while(*s==' ') ++s;
return ;
} char str[];
string name[MAXN<<];
int main(){
int w[MAXN]; char ts[MAXN];
while(gets(str) && str[]!='#'){
char *s=str;
read(s,n); read(s,k); int nn=;
vector<string> vec[MAXN];
for(int i=; i<n; ++i){
gets(str); s=str;
read(s,ts); name[nn++]=ts; vec[i].push_back(ts);
read(s,w[i]);
while(read(s,ts)){
name[nn++]=ts; vec[i].push_back(ts);
}
}
sort(name+,name+nn);
nn=unique(name+,name+nn)-name; NE=;
memset(head,-,sizeof(head));
int deg[MAXN]={};
for(int i=; i<n; ++i){
int u=lower_bound(name+,name+nn,vec[i][])-name;
cost[u]=w[i];
for(int j=; j<vec[i].size(); ++j){
int v=lower_bound(name+,name+nn,vec[i][j])-name;
addEdge(u,v); ++deg[v];
}
}
for(int i=; i<=n; ++i){
if(deg[i]==) addEdge(,i);
} getsize();
for(int i=; i<=n; ++i){
for(int j=; j<=n; ++j) d[i][j]=INF;
}
dfs();
int res=INF;
for(int i=k; i<=n; ++i) res=min(res,d[][i]);
printf("%d\n",res);
}
return ;
}

POJ3345 Bribing FIPA(树形DP)的更多相关文章

  1. POJ 3345 Bribing FIPA 树形DP

    题目链接: POJ 3345 Bribing FIPA 题意: 一个国家要参加一个国际组织,  需要n个国家投票,  n个国家中有控制和被控制的关系, 形成了一颗树. 比如: 国家C被国家B控制, 国 ...

  2. poj3345 Bribing FIPA【树形DP】【背包】

    Bribing FIPA Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5910   Accepted: 1850 Desc ...

  3. POJ3345 Bribing FIPA 【背包类树形dp】

    题目链接 POJ 题解 背包树形dp板题 就是读入有点无聊,浪费了很多青春 #include<iostream> #include<cstdio> #include<cm ...

  4. poj 3345 Bribing FIPA (树形背包dp | 输入坑)

    题目链接:  poj-3345  hdu-2415 题意 有n个国家,你要获取m个国家的支持,获取第i个国家的支持就要给cost[i]的价钱    其中有一些国家是老大和小弟的关系,也就是说,如果你获 ...

  5. POJ3345 Bribing FIPA

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5021   Accepted: 1574 Description There ...

  6. 【转】【DP_树形DP专辑】【9月9最新更新】【from zeroclock's blog】

    树,一种十分优美的数据结构,因为它本身就具有的递归性,所以它和子树见能相互传递很多信息,还因为它作为被限制的图在上面可进行的操作更多,所以各种用于不同地方的树都出现了,二叉树.三叉树.静态搜索树.AV ...

  7. 【DP_树形DP专题】题单总结

    转载自 http://blog.csdn.net/woshi250hua/article/details/7644959#t2 题单:http://vjudge.net/contest/123963# ...

  8. HDU 2415 Bribing FIPA

    Bribing FIPA Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original I ...

  9. Bribing FIPA

    Bribing FIPA 给出多棵有n个节点的有根树,第i个节点有一个权值\(a_i\),定义一个点能控制的点为其所有的子节点和它自己,询问选出若干个点的最少的权值之和,并且能够控制大于等于m个点,\ ...

随机推荐

  1. 三 APPIUM GUI讲解(Windows版)

    本文本转自:http://www.cnblogs.com/sundalian/p/5629386.html APPIUM GUI讲解(Windows版)   Windows版本的APPIUM GUI有 ...

  2. gradle构建

    https://blog.csdn.net/baidu_30809315/article/details/77865414

  3. Python中关于split和splitext的差别和运用

    在使用Python的过程中,在处理字符串的时候会遇到split()和os.path.split()两个函数,他们的主要区别可以概括为一个从前往后搜索字符串,后者则是从后往前搜索 '.'(reverse ...

  4. lowercase calligraphic letters

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/53454402 LaTeX公式表达中,经 ...

  5. atom插件之less-autocompile

    less-autocompile package Auto compile LESS file on save. Add the parameters on the first line of the ...

  6. Nagios 监控系统架设全攻略

    Nagios 全名为(Nagios Ain’t Goona Insist on Saintood),最初项目名字是 NetSaint.它是一款免费的开源 IT 基础设施监控系统,其功能强大,灵活性强, ...

  7. P2324 [SCOI2005]骑士精神

    题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位.两组数据之间没有空行. 输出格式 ...

  8. POJ 1236 Networks of School Tarjan 基础

    题目大意: 给一个有向图,一个文件可以从某个点出发传递向他能连的边 现在有两个问题 1.至少需要多少个放文件可以让整个图都有文件 2.可以进行一个操作:给一对点(u,v)连一条u->v的有向边, ...

  9. HDU 4910 HDOJ Problem about GCD BestCoder #3 第四题

    首先 m = 1 时 ans = 0对于 m > 1 的 情况 由于 1 到 m-1 中所有和m互质的数字,在 对m的乘法取模 运算上形成了群 ai = ( 1<=a<m & ...

  10. 洛谷 P1503 鬼子进村 解题报告

    P1503 鬼子进村 题目背景 小卡正在新家的客厅中看电视.电视里正在播放放了千八百次依旧重播的<亮剑>,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战. ...