zoukankan      html  css  js  c++  java
  • poj 1947 Rebuilding Roads 夜

    http://poj.org/problem?id=1947

    给你一棵n个节点的树 问你保存p个节点的子树最少需要切断多少条边

    我用邻接表保存树

    ans[i][j] 代表了包含i在内的它所要子节点和兄弟子树在内 保存j个点需要最少切断多少边

    代码及其注释:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<algorithm>
    #define LL long long
    
    using namespace std;
    
    const int N=155;
    const int M=1000001;
    struct node
    {
        struct tt *next;
    }mem[N];
    struct tt
    {
        int j;
        struct tt *next;
    };
    int ans[N][N];
    void build(int i,int j)
    {
        struct tt *t=new tt;
        t->j=j;
        t->next=mem[i].next;
        mem[i].next=t;
    }
    void Dele(int n)
    {
        struct tt *t;
        for(int i=1;i<=n;++i)
        {
            while(mem[i].next!=NULL)
            {
                t=mem[i].next;
                mem[i].next=t->next;
                delete t;
            }
        }
    }
    int dp(struct tt *t,int k)
    {
        if(t==NULL)//如果为空了
        {
            if(k==0)//保存0个的话反回0
            return 0;
            else
            return M;//否则反回最大
        }
        if(ans[t->j][k]!=-1)
        return ans[t->j][k];
        if(k==0)//保存0 个的话 需要切断所以兄弟节点与负节点的连线
        {
            ans[t->j][k]=1+dp(t->next,k);
            return ans[t->j][k];
        }
        ans[t->j][k]=1+dp(t->next,k);//此节点子树与父节点切断
        for(int i=1;i<=k;++i)
        {
            //递归找最优
            ans[t->j][k]=min(ans[t->j][k],dp(mem[t->j].next,i-1)+dp(t->next,k-i));
        }
        return ans[t->j][k];
    }
    int main()
    {
        int n,k;
        while(scanf("%d %d",&n,&k)!=EOF)
        {
            for(int i=1;i<n;++i)
            {
                int x,y;
                scanf("%d %d",&x,&y);
                build(x,y);
            }
            if(n==1)
            {
                printf("0\n");
                continue;
            }
            int MIN=M;
            memset(ans,-1,sizeof(ans));
            MIN=min(MIN,dp(mem[1].next,k-1));
            for(int i=2;i<=n;++i)
            {
                MIN=min(MIN,1+dp(mem[i].next,k-1));//不一定值保存 1
            }
    
            printf("%d\n",MIN);
            Dele(n);
        }
    }
    

      

  • 相关阅读:
    Eclipse背景颜色设置
    SQL ROW_NUMBER() OVER函数的基本用法用法
    hdu 2844 Coins 多重背包问题
    VC++学习/MFC (1)
    java学习 (1)
    hdu 1506 City Game 二维的多重背包
    java学习(2)
    VC++学习/MFC (2)
    hdu 1506 Largest Rectangle in a Histogram
    hdu 1171 Big Event in HDU
  • 原文地址:https://www.cnblogs.com/liulangye/p/2604561.html
Copyright © 2011-2022 走看看