zoukankan      html  css  js  c++  java
  • bzoj1808: [Ioi2007]training 训练路径

    首先我们先挖掘一下性质

    对于一条非树边,假如他的两个节点的树上距离为奇数,那就必须删掉

    处理完这个以后,再考虑一下两条非树边的各自的两个节点的树上路径相交的情况

    假如相交为奇(偶)数条边,那么没相交的那两段分别就会有偶(奇)数条边,偶(奇)+偶(奇)+两条非树边,可以构成偶环

    所以最后删剩下的会是一棵仙人掌,我们可以反过来,算留下来的边最大

    我们可以这样想,对于一条非树边,他占用的是他两段端点的树上路径,占用了的路径不能再被占用

    上treeDP,设f[i][zt]表示第i个点的子树中,zt的第j位表示第j个孩子,0表示没有被删,1表示被删了

    在LCA处枚举边,对于这条树上路径可以看成把树分拆成了几块,暴力枚举这些块并更新即可

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    using namespace std;
    
    struct node
    {
        int x,y,next;
    }a[2100];int len,last[1100];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int Bin[20];
    int f[20][1100],dep[1100];
    vector<int>son[1100];int wih[1100];
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        for(int i=15;i>=0;i--)
            if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
        if(x==y)return x;
        for(int i=15;i>=0;i--)
            if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];
        return f[0][x];
    }
    void init(int x)
    {
        for(int i=1;Bin[i]<=dep[x];i++)f[i][x]=f[i-1][f[i-1][x]];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(f[0][x]!=y)
            {
                f[0][y]=x;
                dep[y]=dep[x]+1;
                son[x].push_back(y);
                wih[y]=son[x].size()-1;
                init(y);
            }
        }
    }
    
    struct edge
    {
        int x,y,d;
        edge(){}
        edge(int X,int Y,int D){x=X,y=Y,d=D;}
    }e[5100];int elen;
    vector<int>vec[1100];
    
    int g[1100][1100];
    void treeDP(int x)
    {
        for(int i=0;i<son[x].size();i++)treeDP(son[x][i]);
        for(int zt=(1<<son[x].size())-1;zt>=0;zt--)
        {
            g[x][zt]=0;
            for(int i=0;i<son[x].size();i++)
                if(!(zt&(1<<i)))g[x][zt]+=g[son[x][i]][0];
        }
            
        int mmax=g[x][0];
        for(int k=0;k<vec[x].size();k++)
        {
            int p=vec[x][k];
            int u=e[p].x,v=e[p].y;
            
            int d=e[p].d,z=0;
            if(u!=x&&v!=x)
            {
                int c1,c2;
                c1=u;d+=g[u][0];
                for(int o=f[0][c1];o!=x;c1=f[0][c1],o=f[0][o])d+=g[o][1<<wih[c1]];
                c1=wih[c1];
                    
                c2=v;d+=g[v][0];
                for(int o=f[0][c2];o!=x;c2=f[0][c2],o=f[0][o])d+=g[o][1<<wih[c2]];
                c2=wih[c2];
                    
                z=((1<<c1)|(1<<c2));
            }
            else
            {
                if(v!=x)swap(u,v);
                int c1;
                c1=u;d+=g[u][0];
                for(int o=f[0][c1];o!=x;c1=f[0][c1],o=f[0][o])d+=g[o][1<<wih[c1]];
                c1=wih[c1];
                    
                z=(1<<c1);
            }
            for(int zt=(1<<son[x].size())-1;zt>=0;zt--)
                if((zt&z)==0)g[x][zt]=max(g[x][zt],d+g[x][zt|z]);
        }
    }
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int n,m,sum=0,x,y,dd;
        scanf("%d%d",&n,&m);elen=0;
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&dd);
            if(dd==0)ins(x,y),ins(y,x);
            else e[++elen]=edge(x,y,dd),sum+=dd;
        }
    
        Bin[0]=1;for(int i=1;i<=17;i++)Bin[i]=Bin[i-1]*2;
        f[0][1]=0;dep[1]=0;init(1);
        for(int i=1;i<=elen;i++)
        {
            if((dep[e[i].x]+dep[e[i].y]+1)%2==1)
            {
                int lca=LCA(e[i].x,e[i].y);
                vec[lca].push_back(i);
            }
        }
        treeDP(1);
        printf("%d
    ",sum-g[1][0]);
        
        return 0;
    }
  • 相关阅读:
    Java Web 网络留言板2 JDBC数据源 (连接池技术)
    Java Web 网络留言板3 CommonsDbUtils
    Java Web ConnectionPool (连接池技术)
    Java Web 网络留言板
    Java Web JDBC数据源
    Java Web CommonsUtils (数据库连接方法)
    Servlet 起源
    Hibernate EntityManager
    Hibernate Annotation (Hibernate 注解)
    wpf控件设计时支持(1)
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9852529.html
Copyright © 2011-2022 走看看