我的第一道邻接表存图成功的题! ✿✿ヽ(°▽°)ノ✿
配有超详细的代码注释,顺便复习一下邻接表存图,注:这里的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\n",ans); }