codevs 1746 贪吃的九头龙

/*
状态定义的没错 就是考试的时候傻啦吧唧的转移左右孩子
其实之转移父亲就简单多了 不用考虑那么多
还有就是偷懒没有把谁有没有找过这个信息转过去
而是搞了个全局变量…wa到挺
再就是特盘的时候还有终止条件写的不好
写的时间也很长 …..
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 510
#define inf 0x3f3f3f3f
using namespace std;
int n,m,K,num,head[maxn],fa[maxn],lc[maxn],rc[maxn],dis[maxn];
int son[maxn][maxn],s[maxn],f[maxn][maxn][2],V[maxn];
struct node{int u,v,t,pre;}e[maxn*2];
void Add(int from,int to,int dis)
{
    num++;e[num].u=from;
    e[num].v=to;e[num].t=dis;
    e[num].pre=head[from];
    head[from]=num;
}
void Dfs(int now,int from)
{
    fa[now]=from;
    for(int i=head[now];i;i=e[i].pre)
      if(e[i].v!=from)
        {
          son[now][++s[now]]=e[i].v;
          dis[e[i].v]=e[i].t;
          Dfs(e[i].v,now);
        }
}
void Build()
{
    for(int i=1;i<=n;i++)
      for(int j=1;j<=s[i];j++)
        {
          int u=i,v=son[i][j];
          if(lc[u]==0){lc[u]=v;continue;}
          u=lc[u];while(rc[u])u=rc[u];
          rc[u]=v;
        }
}
int C(int t)
{
  if(m==2&&t==0)return 1;
  else return 0;
}
int DP(int k,int p,int t)
{
    if(k==0&&p)return f[k][p][t]=inf;
    if(f[k][p][t]>=0)return f[k][p][t];
    if(k==0&&p==0)return 0;
    int r=inf;
    for(int i=0;i<=p;i++)
      {
          int s1=p-i,s2=i;
          r=min(r,DP(lc[k],s1,0)+DP(rc[k],s2,t)+C(t)*dis[k]);
      }
    for(int i=0;i<=p-1;i++)
      {
          int s1=p-i-1,s2=i;
          r=min(r,DP(lc[k],s1,1)+DP(rc[k],s2,t)+t*dis[k]);
      }
    return f[k][p][t]=r;
}
int main()
{
    scanf("%d%d%d",&n,&m,&K);
    if(n-K<m-1){printf("-1\n");return 0;}
    memset(f,-1,sizeof(f));
    int a,b,c;
    for(int i=1;i<n;i++)
      {
          scanf("%d%d%d",&a,&b,&c);
          Add(a,b,c);Add(b,a,c);
      }
    Dfs(1,1);Build();V[1]=1;
    printf("%d\n",DP(lc[1],K-1,1));
    return 0;
}

 

posted @ 2016-08-17 20:11  一入OI深似海  阅读(167)  评论(0编辑  收藏  举报