• Contest20140709 testA 树型DP


    1. testA


    输入文件: testA.in 输出文件testA.out 时限5000ms


    问题描述:


    一棵树N个节点,每条边有一个距W,现在定义SUM为所有dist(X,Y)的和1<=X<Y<=N , dist(X,Y)表示XY在树上的距离。现在给你一个机会把任意一条边删掉,再把这条边连接其他两个节点使得SUM最小。求出SUM的最小值



    输入描述:


    第一行N

    第二行到第N行每行三个数X,Y,W。表示XY有一条长度为W的边。


    输出描述:


    一行一个数表示答案。


    数据范围N<=5000 , W<=10^6


    样例输入1

    6
    1 2 1
    2 3 1
    3 4 1
    4 5 1
    5 6 1


    样例输出1

    29


    样例输入2

    3
    1 2 2
    1 3 4


    样例输出2

    12


    就因为这道题卡了我很久啊。总之就是维护一堆乱七八糟的值。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define MAXN 10000
    #define MAXE MAXN*2
    #define MAXV MAXN
    #ifdef WIN32
    #define LL "%I64d"
    #else
    #define LL "%lld"
    #endif
    typedef long long qword;
    int n,m;
    struct edge
    {
            int x,y;
    }el[MAXE];
    struct Edge
    {
            int np,val;
            int id;
            Edge *next;
    }E[MAXE],*V[MAXV];
    int root,tope=-1;
    void addedge(int x,int y,int z,int id)
    {
            E[++tope].np=y;
            E[tope].next=V[x];
            E[tope].val=z;
            E[tope].id=id;
            V[x]=&E[tope];
    }
    int fa[MAXN];
    int dis_fa[MAXN];
    int q[MAXN];
    int ope=-1,clo=0;
    int dp1[MAXN];//size of subtree
    qword dp2[MAXN];//the total distance from each child to the root in subtree
    qword dp3[MAXN];//the total distance from each node outside the subtree to root 
    qword dp4[MAXN];//the total distance of each pair
    void bfs(int root)
    {
            ope=-1,clo=0;
            Edge *ne;
            q[0]=root;
            fa[root]=0;
            int now;
            while (ope<clo)
            {
                    now=q[++ope];
                    for (ne=V[now];ne;ne=ne->next)
                    {
                            if (ne->np==fa[now])continue;
                            fa[ne->np]=now;
                            dis_fa[ne->np]=ne->val;
                            q[++clo]=ne->np;
                    }
            }
    }
    qword  work1()
    {
            int i,j;
            Edge *ne;
            int now;
            for (i=clo;i>=0;i--)
            {
                    now=q[i];
                    dp1[now]=1;
                    for (ne=V[now];ne;ne=ne->next)
                    {
                            if (ne->np==fa[now])continue;
                            dp1[now]+=dp1[ne->np];
                    }
            }
            for (i=clo;i>=0;i--)
            {
                    now=q[i];
                    dp2[now]=0;
                    for (ne=V[now];ne;ne=ne->next)
                    {
                            if (ne->np==fa[now])continue;
                            dp2[now]+=dp2[ne->np]+dp1[ne->np]*ne->val;
                    }
            }
            dp3[q[0]]=0;
            for (i=1;i<=clo;i++)
            {
                    now=q[i];
    //                dp3[now]=dp3[fa[now]]+dp2[fa[now]]-dp2[now]+dis_fa[now]*(-dp1[now]+dp1[fa[now]]-dp1[now]);
                    dp3[now]=dp3[fa[now]]+dp2[fa[now]]-dp2[now]-dis_fa[now]*dp1[now]+dis_fa[now]*(dp1[root]-dp1[now]);
            }
            qword ret=0;
            for (i=1;i<=n;i++)
            {
                    ret+=(qword)dis_fa[i]*dp1[i]*(dp1[root]-dp1[i]);
            }
            return ret;
    }
    bool edge_st[MAXN];
    int color[MAXN];
    qword dist[MAXN];
    void dfs2(int now,int fat,int col,qword d)
    {
            color[now]=col;
            dist[now]=d;
            Edge *ne;
            for (ne=V[now];ne;ne=ne->next)
            {
                    if (ne->np==fat)continue;
                    dfs2(ne->np,now,col,d+ne->val);
            }
    }
    int main()
    {
            freopen("testA.in","r",stdin);
            //freopen("testA.out","w",stdout);
            int i,j,k;
            int x,y,z;
            scanf("%d",&n);
            for (i=1;i<n;i++)
            {
                    scanf("%d%d%d",&x,&y,&z);
                    addedge(x,y,z,i-1);
                    addedge(y,x,z,i-1);
                    el[i-1].x=x;
                    el[i-1].y=y;
            }
            m=n-1;
            root=1;
            bfs(root);
            qword sum_old=work1();
            //cout<<"SUM_OLD:"<<sum_old<<endl;
            qword dis1,dis2;
            qword dis_old1,dis_old2;
            qword mus1,mus2;
            int totm1,totm2;
            qword best=0;
            for (i=0;i<m;i++)
            {
                    edge_st[i]=1;
                    if (fa[el[i].x]==el[i].y)swap(el[i].x,el[i].y);
                    dfs2(el[i].x,el[i].y,1,0);//1:outside
                    dfs2(el[i].y,el[i].x,2,0);//2:inside
                    dis_old1=dp3[el[i].y]-dis_fa[el[i].y]*(dp1[root]-dp1[el[i].y]);
                    dis_old2=dp2[el[i].y];
                    mus1=dp2[el[i].y]+dp1[el[i].y]*dis_fa[el[i].y];
                    mus2=dp3[el[i].y];
                    totm1=dp1[el[i].y];
                    totm2=dp1[root]-dp1[el[i].y];
                    dis1=dis2=INF;
                    for (j=1;j<=n;j++)
                    {
                            if (color[j]==2)
                            {
                                    dis2=min(dis2,dp2[j]+dp3[j]-mus2-totm2*dist[j]);
                            }else
                            {
                                    dis1=min(dis1,dp2[j]+dp3[j]-mus1-totm1*dist[j]);
                            }
                    }
                    best=max(best,(dis_old1-dis1)*totm1+(dis_old2-dis2)*totm2);
            }
            printf(LL "
    ",sum_old-best);
            return 0;
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    解决pip3的ImportError: cannot import name 'main'
    linux 安装Python3.6
    Linux安装redis和部署
    redis密码管理
    CentOS7使用firewalld打开关闭防火墙与端口
    scrapy 从Windwos平台移植到 Linux平台之实操
    Linux 环境下安装Maven
    解决:安装Jenkins时web界面出现该jenkins实例似乎已离线
    持续集成工具Jenkins结合SVN的安装和使用
    Linux下的SVN服务器搭建
  • 原文地址:https://www.cnblogs.com/mhy12345/p/3887702.html
Copyright © 2020-2023  润新知