POJ-Rebuilding Roads 树形DP

来源:互联网 发布:济南搜索引擎优化外包 编辑:程序博客网 时间:2024/05/18 17:01

题目链接



#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<math.h>#include<functional>#include<algorithm>#include<vector>#include<queue>using namespace std;const int maxn = 155;const int inf = 1<<29;typedef __int64 LL;int n,p;int dp[maxn][maxn];  //dp[i][j] 以i结点为根节点 得到j个结点的子树需要减去的最少边bool vis[maxn];vector<int>map[maxn];void dfs( int u ){vis[u] = 1;for( int i = 0; i <= p; i ++ )dp[u][i] = inf;dp[u][1] = 0;            for( int i = 0; i < map[u].size(); i ++ ){int v = map[u][i];if( vis[v] )continue;dfs(v);for( int j = p; j >= 1; j -- ){int tmp = dp[u][j] + 1;   //去掉v结点 切去u与v的连边 故要加一for( int k = 1; k < j; k ++ )  //不去掉v结点 u树中原有的k个结点与v结点中j-k个结点构成j个结点tmp = min( tmp,dp[u][k] + dp[v][j-k] );dp[u][j] = tmp;}}}int fun(){dfs( 1 );int ans = dp[1][p];    //根结点不用去掉与父节点的连边for( int i = 1; i <= n; i ++ ){if( ans > dp[i][p] + 1 )ans = dp[i][p] + 1;}return ans;}void init(){for( int i = 0; i <= n; i ++ )map[i].clear();memset( vis,0,sizeof(vis) );}int main() {#ifndef ONLINE_JUDGE    freopen("data.txt","r",stdin);#endifint u,v;while( scanf("%d%d",&n,&p) != EOF ){init();for( int i = 0; i < n-1; i ++ ){scanf("%d%d",&u,&v);map[u].push_back(v);map[v].push_back(u);}printf("%d\n",fun());}    return 0;}


0 0
原创粉丝点击