1808: [Ioi2007]training 训练路径|树形DP

Posted ws_yzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1808: [Ioi2007]training 训练路径|树形DP相关的知识,希望对你有一定的参考价值。

http://adn.botao.hu/?p=80胡波涛的题解说的很详细,这里就不赘述了

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<ctime>
#include<set>
#include<map>
#define N 1111
#define M 5500
using namespace std;
int f[N][1<<10];
int fa[N],S[N][11],size[N],deep[N];
int head[N],lst[M<<1],nxt[M<<1];
int a[M],b[M],c[M],num[N][N];
int n,m,tot,cnt,CN,sum;
struct Wint a,b,c;;
vector<W>w[N];
void insert(int x,int y)

    lst[++tot]=y;nxt[tot]=head[x];head[x]=tot;
    lst[++tot]=x;nxt[tot]=head[y];head[y]=tot;

void dfs1(int x,int f)

    for(int i=head[x];i;i=nxt[i])
        if(lst[i]!=f)
        
            deep[lst[i]]=deep[x]+1;
            fa[lst[i]]=x;
            S[x][size[x]++]=lst[i];
            dfs1(lst[i],x);
            num[x][lst[i]]=size[x]-1;
        

int Lca(int x,int y)

    if(deep[x]<deep[y])swap(x,y);
    while(deep[x]!=deep[y])x=fa[x];
    while(fa[x]!=fa[y])x=fa[x],y=fa[y];
    return x==y?x:fa[x];

int rel[M],bel[M];
void DP(int x)

    for(int i=head[x];i;i=nxt[i])
        if(lst[i]!=fa[x])DP(lst[i]);
    for(int i=0;i<w[x].size();i++)
    
        int qa=w[x][i].a,qb=w[x][i].b,qc=w[x][i].c;
        bel[i]=0;
        if(qa!=x)
        
            qc+=f[qa][(1<<size[qa])-1];
            while(fa[qa]!=x)
            
                int F=fa[qa];
                qc+=f[F][((1<<size[F])-1)^(1<<num[F][qa])];
                qa=F;
            
            bel[i]|=(1<<num[x][qa]);
        
        qa=qb;
        if(qa!=x)
        
            qc+=f[qa][(1<<size[qa])-1];
            while(fa[qa]!=x)
            
                int F=fa[qa];
                qc+=f[F][((1<<size[F])-1)^(1<<num[F][qa])];
                qa=F;
            
            bel[i]|=(1<<num[x][qa]);
        
        rel[i]=qc;
    
    for(int i=1;i<(1<<size[x]);i++)
    
        for(int j=0;j<size[x];j++)
            if((1<<j)&i)f[x][i]+=f[S[x][j]][(1<<size[S[x][j]])-1];
        for(int j=0;j<w[x].size();j++)
            if((bel[j]&i)==bel[j])
                f[x][i]=max(f[x][i],f[x][i^bel[j]]+rel[j]);
    
           
int main()

    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    
        scanf("%d%d%d",&a[cnt],&b[cnt],&c[cnt]);
        if(c[cnt]==0)
             insert(a[cnt],b[cnt]);
        else cnt++;
    
    dfs1(1,0);
    CN=cnt;cnt=0;
    for(int i=0;i<CN;i++)
    
        int lca=Lca(a[i],b[i]);
        if((deep[a[i]]+deep[b[i]]-2*deep[lca]&1)==0)
            w[lca].push_back((W)a[i],b[i],c[i]);
        sum+=c[i];
    
    DP(1);
    cout<<sum-f[1][(1<<size[1])-1];
    return 0;

以上是关于1808: [Ioi2007]training 训练路径|树形DP的主要内容,如果未能解决你的问题,请参考以下文章

1806: [Ioi2007]Miners 矿工配餐

BZOJ1806[Ioi2007]Miners 矿工配餐 DP

bzoj 1806 [Ioi2007]Miners 矿工配餐(DP)

Vijos1386 IOI2007 矿工配餐 动态规划

矿工配餐_IOI2007Miners

bzoj1805: [Ioi2007]Sail 船帆