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

来源:互联网 发布:搜索引擎源码 编辑:程序博客网 时间:2024/06/03 19:04

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 5500using 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 W{int 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;}
0 0