POJ 3345 Bribing FIPA 树形dp
2012-04-01 13:57
267 查看
http://poj.org/problem?id=3345
题意 :给定N个国家,相互之间可能存在附属关系,现在想要贿赂m个国家,已知,贿赂一个国家,那么如果该国家拥有附属国,那么他的所有附属国都可以算作已经贿赂。
思路:树形dp。dp[u][j]:表示在以u为根的子树中选出j个国家的最小花费。这里在求以u为根的子树中选出j个国家的花费的时候还是用dfs 的方法,先求出孩子结点的值,然后从叶子结点递归上去,进行一次背包,求出一u为根的子树中找出j个国家的最小费用。还有很多的细节需要注意,具体见代码注释。
代码:
题意 :给定N个国家,相互之间可能存在附属关系,现在想要贿赂m个国家,已知,贿赂一个国家,那么如果该国家拥有附属国,那么他的所有附属国都可以算作已经贿赂。
思路:树形dp。dp[u][j]:表示在以u为根的子树中选出j个国家的最小花费。这里在求以u为根的子树中选出j个国家的花费的时候还是用dfs 的方法,先求出孩子结点的值,然后从叶子结点递归上去,进行一次背包,求出一u为根的子树中找出j个国家的最小费用。还有很多的细节需要注意,具体见代码注释。
#include <cstdio> #include <cstring> #define MIN(a,b) (a)>(b)?(b):(a) const int INF = 0x3f3f3f3f ; char ch[210] ; int N ,M ; char name[210][110],na[110]; bool map[210][210] ; int V[210], d[210]; int vote[210] ; int dp[210][210] ; int cnt ; int find(char *p){ for(int i=1;i<cnt;i++){ if(strcmp(p , name[i]) == 0) return i ; } strcpy(name[cnt] , p); cnt ++ ; return cnt - 1 ; } void Input(){ int i , j ,k ,f,len,u,a ,v; sscanf(ch,"%d%d",&N,&M); memset(map , 0 ,sizeof(map) ); memset( d , 0 , sizeof(d) ); cnt = 1 ; for(i=1;i<=N;i++){ scanf("%s%d",ch,&a); u = find(ch) ; V[u] = a ; while(getchar() != '\n'){ scanf("%s",ch); v = find(ch) ; map[u][v] = 1 ; d[v] ++ ; } } } void dfs(int u){ int res = 1 ; for(int i=1;i<=N;i++){ if(map[u][i] == 1){ dfs(i); res += vote[i] ; } } vote[u] = res ; } void Build(int u){ //建树 for(int i=1;i<=N;i++){ if(d[i]) continue ; map[u][i] = 1 ; } V[0] = INF ; dfs(0); vote[0] = N + 1; } int DP(int u){ dp[u][0] = 0 ; //只有根结点一个结点,此时先假定根结点不选。 int nn = 0 ; //当前根结点总共可以选择的国家数。 for(int v=1;v<=N;v++){ if(map[u][v] == 0) continue ; nn += DP(v) ; for(int j=nn;j>=0;j--){ for(int k=1;k<=j;k++){ if(dp[u][j-k]<INF && dp[v][k]<INF && dp[u][j]>dp[u][j-k]+dp[v][k]){ dp[u][j] = dp[u][j-k] + dp[v][k] ; } } } } for(int i=1;i<=vote[u];i++){ //题目的关键:若选择了根结点,则相应的孩子全选。此处更新必须。 dp[u][i] = MIN( dp[u][i] , V[u]); } return nn + 1; //返回以u为根的子树的国家的数目 } int main(){ while(true){ gets(ch); if(ch[0] == '#') break ; Input() ; Build(0); memset(dp,0x3f ,sizeof(dp) ); DP(0); printf("%d\n",dp[0][M]); } return 0 ; }
代码:
相关文章推荐
- poj 3345 Bribing FIPA 树形dp
- POJ 3345 Bribing FIPA 树形DP
- POJ 3345 Bribing FIPA 树形DP
- poj 3345 Bribing FIPA 树形dp
- (中等) 树形dp(分组背包) POJ 3345 Bribing FIPA
- POJ3345 Bribing FIPA 【背包类树形dp】
- poj 3345 树形DP 附属关系+输入输出(好题)
- poj 3345 Bribing FIPA(树形dp)
- poj 3345 树形dp(收买国家)
- POJ 3345(树形dp)
- POJ 3345——Bribing FIPA(树形DP)
- POJ-3345(树形DP)
- POJ-3345 Bribing FIPA 树形DP+分组背包
- poj 3345 Bribing FIPA 【树形dp + 01背包】
- POJ 3345 Bribing FIPA(树形DP)
- POJ 3345 Bribing FIPA / 树形DP
- poj 3345 Bribing FIPA[树形dp+背包]
- poj 3345 树形dp
- poj 3345 Bribing FIPA (树形背包dp | 输入坑)
- poj 3345 Bribing FIPA (树形背包dp | 输入坑)