test20181029 宝藏

Posted autoint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了test20181029 宝藏相关的知识,希望对你有一定的参考价值。

题意

技术分享图片

分析

考场做法

一眼看出是支持换根的树形dp。

(f(x,0/1))表示x及其子树中,从x出发,不一定/一定回到x的最大收益。

然后子树很好做。

换根的时候,我先计算后还原,需要考虑很多,调了很久。

后来知道可以用up,down状态转移,会好写一些,但要考虑得跟我先前打的差不多。

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#include<cassert>
#define rg register
#define il inline
#define co const
#pragma GCC optimize ("O0")
using namespace std;
template<class T> il T read()
{
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==‘-‘)
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-‘0‘,ch=getchar();
    return data*w;
}
template<class T> il T read(T&x)
{
    return x=read<T>();
}
typedef long long ll;
const int INF=0x7fffffff;

co int MAXN=3e5+7;

struct Edge
{
    int nx,to,w;
}E[MAXN<<1];
int head[MAXN],ecnt;

il void addedge(rg int x,rg int y,rg int w)
{
    E[++ecnt].to=y,E[ecnt].w=w;
    E[ecnt].nx=head[x],head[x]=ecnt;
}

int fa[MAXN],fw[MAXN];
int val[MAXN];

ll f[MAXN][2];
int maxv[MAXN],secv[MAXN];

il ll take(rg int y)
{
    return max(0LL,f[y][0]-fw[y]);
}

il ll fetch(rg int y)
{
    return max(0LL,f[y][1]-2*fw[y]);
}

il ll calc(rg int y)
{
    return take(y)-fetch(y);
}

il void dfs1(rg int x,rg int fath)
{
    fa[x]=fath;
    f[x][1]=val[x];
    for(rg int i=head[x];i;i=E[i].nx)
    {
        rg int y=E[i].to,w=E[i].w;
        if(y==fath)
        {
            fw[x]=w;
            continue;
        }
        dfs1(y,x);
        f[x][1]+=fetch(y);
    }
    f[x][0]=f[x][1];
    for(rg int i=head[x];i;i=E[i].nx)
    {
        rg int y=E[i].to;
        if(y==fath)
            continue;
        if(calc(y)>calc(secv[x]))
        {
            secv[x]=y;
            if(calc(secv[x])>calc(maxv[x]))
                swap(secv[x],maxv[x]);
        }
    }
    f[x][0]+=calc(maxv[x]);
}

ll fet[MAXN],calsec[MAXN],cal[MAXN];

il void dfs2(rg int x)
{
    if(fa[x])
    {    // f[fa] shouldn‘t change
        fet[x]=fetch(x);
        cal[x]=calc(x);
        f[fa[x]][1]-=fet[x];
        f[fa[x]][0]-=fet[x];
        rg int w=fw[fa[x]];
        fw[fa[x]]=fw[x];
        f[x][1]+=fetch(fa[x]);
        f[x][0]=f[x][1];
        if(maxv[fa[x]]==x)
        {
            f[fa[x]][0]-=cal[x];
            f[fa[x]][0]+=calsec[fa[x]];
        }
        if(calc(fa[x])>calc(secv[x]))
        {
            secv[x]=fa[x];
            if(calc(secv[x])>calc(maxv[x]))
                swap(secv[x],maxv[x]);
        }
        calsec[x]=calc(secv[x]);
        f[x][0]+=calc(maxv[x]);
        
        f[fa[x]][1]+=fet[x]; // restore
        f[fa[x]][0]+=fet[x];
        fw[fa[x]]=w;
        if(maxv[fa[x]]==x)
        {
            f[fa[x]][0]-=calsec[fa[x]];
            f[fa[x]][0]+=cal[x];
        }
    }
    else
    {
        fet[x]=fetch(x);
        calsec[x]=calc(secv[x]);
        cal[x]=calc(x);
    }
    
    for(rg int i=head[x];i;i=E[i].nx)
    {
        rg int y=E[i].to;
        if(y==fa[x])
            continue;
        dfs2(y);
    }
}

int main()
{
  freopen("treasure.in","r",stdin);
  freopen("treasure.out","w",stdout);
    rg int n=read<int>();
    for(rg int i=1;i<n;++i)
    {
        rg int x=read<int>(),y=read<int>(),w=read<int>();
        addedge(x,y,w);
        addedge(y,x,w);
    }
    for(rg int i=1;i<=n;++i)
    {
        read(val[i]);
    }
    dfs1(1,0);
    dfs2(1);
/*  for(int i=1;i<=n;++i)
    {
        printf("%d:
",i);
        printf(" f0=%lld	f1=%lld
",f[i][0],f[i][1]);
    }*/
    for(rg int i=1;i<=n;++i)
    {
        printf("%lld
",f[i][0]);
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

标解

技术分享图片

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<bitset>
using namespace std;
typedef long long ll;
const int N=610000;
int fi[N],ne[N],len[N],to[N];
ll dp0[N],dp1[N];
ll ans[N],wushi0[N],wushi1[N],val[N];
int pE,n;
//0:考虑回到原点;1:不回到原点 
void addE(int u,int v,int l)
{
    pE++;to[pE]=v;len[pE]=l;
    ne[pE]=fi[u];fi[u]=pE;
}
void dfs(int u,int fa)
{
    ll mx=0;
    for (int j=fi[u];j;j=ne[j])
    {
        if (to[j]==fa) continue;
        dfs(to[j],u);
        if (dp0[to[j]]-2*len[j]>0) 
        {
            dp0[u]+=dp0[to[j]]-2*len[j];
            mx=max(mx,len[j]+dp1[to[j]]-dp0[to[j]]);
        }
        else mx=max(mx,dp1[to[j]]-len[j]);
    }
    dp0[u]+=val[u];
    dp1[u]=dp0[u]+mx;
}
void dfs2(int u,int fa,int le)
{
    ans[u]=max(dp0[u]+max(wushi1[u]-le,(ll)0),dp1[u]+max(wushi0[u]-le*2,(ll)0));
    ll mx1=0,mx2=0;
    for (int j=fi[u];j;j=ne[j])
    {
        if (to[j]==fa) continue;
        ll now;
        if (dp0[to[j]]-2*len[j]>0) now=len[j]+dp1[to[j]]-dp0[to[j]];
            else now=dp1[to[j]]-len[j];
        if (now>mx1) {mx2=mx1;mx1=now;}
            else if (now>mx2) mx2=now;
    }
    ll now;
    if (wushi0[u]-2*le>0) now=le+wushi1[u]-wushi0[u];
        else now=wushi1[u]-le;
    if (now>mx1) {mx2=mx1;mx1=now;}
        else if (now>mx2) mx2=now;
    for (int j=fi[u];j;j=ne[j])
    {
        if (to[j]==fa) continue;
        wushi0[to[j]]=dp0[u]-max((ll)0,dp0[to[j]]-2*len[j])+max((ll)0,wushi0[u]-2*le);
        ll now;
        if (dp0[to[j]]-2*len[j]>0) now=len[j]+dp1[to[j]]-dp0[to[j]];
            else now=dp1[to[j]]-len[j];
        if (now==mx1) wushi1[to[j]]=wushi0[to[j]]+mx2;
            else wushi1[to[j]]=wushi0[to[j]]+mx1;
    }
    for (int j=fi[u];j;j=ne[j])
        if (to[j]!=fa) dfs2(to[j],u,len[j]);
}
int main()
{
freopen("treasure.in","r",stdin);
freopen("treasure.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<n;i++)
    {
        int u,v,l;scanf("%d%d%d",&u,&v,&l);
        addE(u,v,l);addE(v,u,l);
    }
    for (int i=1;i<=n;i++) scanf("%d",&val[i]);
    dfs(1,0);
    for (int j=fi[1];j;j=ne[j])
        if (dp0[to[j]]-2*len[j]>0) 
            wushi0[to[j]]=dp0[1]-(dp0[to[j]]-2*len[j]);
                else wushi0[to[j]]=dp0[1];
    ll mx1=0,mx2=0;
    for (int j=fi[1];j;j=ne[j])
    {
        ll now;
        if (dp0[to[j]]-2*len[j]>0) now=len[j]+dp1[to[j]]-dp0[to[j]];
            else now=dp1[to[j]]-len[j];
        if (now>mx1) {mx2=mx1;mx1=now;}
            else if (now>mx2) mx2=now;
    }
    for (int j=fi[1];j;j=ne[j])
    {
        ll now;
        if (dp0[to[j]]-2*len[j]>0) now=len[j]+dp1[to[j]]-dp0[to[j]];
            else now=dp1[to[j]]-len[j];
        if (now==mx1) wushi1[to[j]]=wushi0[to[j]]+mx2;
            else wushi1[to[j]]=wushi0[to[j]]+mx1;
    }
    ans[1]=dp1[1];
    for (int j=fi[1];j;j=ne[j]) dfs2(to[j],1,len[j]);
    for (int i=1;i<=n;i++) printf("%lld
",ans[i]);
    return 0;
}

以上是关于test20181029 宝藏的主要内容,如果未能解决你的问题,请参考以下文章

text 20181029 config.rbについて

Leetcode刷题记录_20181029

题解 20181029测试:T4 ambassador

20181029noip模拟赛T1

[React Testing] Use Generated Data in Tests with tests-data-bot to Improve Test Maintainability(代码片段

Go开源宝藏CORS 跨域 与 CSRF攻击 | 中间件