交易

我的第一道邻接表存图成功的题! ✿✿ヽ(°▽°)ノ✿

配有超详细的代码注释,顺便复习一下邻接表存图,注:这里的nxt=next。

题目·

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
int n,tot=0,first[maxn],to[maxn*2],w[maxn*2],nxt[maxn*2],d[maxn],f[maxn],g[maxn],ans,a[maxn];
void add(int u,int v,int w_){
    to[++tot]=v;    //这条边连接到的点 
    nxt[tot]=first[u];
    first[u]=tot;   
    w[tot]=w_;  //这条边的值 
}
void dfs(int u,int F){  //u为一个端点 F为前一个端点,不能去掉,后面用它来判断是否结束
    f[u]=-d[u]+a[u];        //u作为卖书的地方所能得到的钱 
    g[u]=-d[u]-a[u];        //u作为买书的地方所能得到的钱 
    for(int i=first[u];i;i=nxt[i]){   //i为第几条边 从u出发的边 
        int v=to[i];           //这条边连接u和v 
        if(v==F) continue;     //当这条边可以去到的点为上一个点时,说明已经遍历完了整棵树
        d[v]=d[u]+w[i];        //v到端点的距离等于u到端点的加上u到v的距离 
        dfs(v,u);              //可以递归出端点的所有子树 
        ans=max(ans,f[u]+g[v]+2*d[u]);  //加上多减的从u到端点的距离 
        ans=max(ans,g[u]+f[v]+2*d[u]);
        f[u]=max(f[u],f[v]);   //dp
        g[u]=max(g[u],g[v]);
    }
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<n;i++){
        int u,v,w;
        cin>>u>>v>>w;
        add(u,v,w);
        add(v,u,w);
    }
    dfs(1,0);
    printf("%d
",ans);
}
原文地址:https://www.cnblogs.com/lxy050129/p/10518157.html