题目链接
看完题就知道是换根dp了,哭哭。
就是分两次dfs,
第一次dfs 用儿子节点更新父亲节点
第二次dfs 用父亲节点更新儿子节点
然后这题需要维护最短路/次短路/次次短路
然后,我的wa点在哪里呢?
第二次dfs的时候,当我们用父亲更新儿子的时候,相当于从父亲过来的路径也是当作儿子的一条路径 且 更新——儿子的(最短路 次短路 次次短路)
#includeusing namespace std; typedef long long ll; #define int ll #define pb push_back #define is insert #define PII pair //mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count()); //ll getRandom(ll l,ll r){return uniform_int_distribution (l,r)(mt19937random);} const int N=1e5+50; const ll INF=0x3f3f3f3f; const ll MOD=1e9+7; int n,m; int d[N]; int head[N]; struct node { int to,nxt; ll val; }e[N<<1]; int idx=0; void add_edge(int u,int v,ll val){ e[idx]={v,head[u],val}; head[u]=idx++; } ll d1[N],d2[N],d3[N];//从以i为根的子树转移上来的最短路 次短路 次次短路 ll p1[N],p2[N];//p1[i]表示 以i为根的子树最短路走到的第一个点 ll rt=1; ll up[N]; ll dfs_d(int u,int pre){ for(int i=head[u];i!=-1;i=e[i].nxt){ ll v=e[i].to,val=e[i].val; if(v==pre)continue; ll d=dfs_d(v,u)+val; if(d>=INF)continue; if(d<=d1[u]){ d3[u]=d2[u],d2[u]=d1[u],d1[u]=d; p2[u]=p1[u],p1[u]=v; } else if(d<=d2[u]){ d3[u]=d2[u];d2[u]=d;p2[u]=v; } else if(d >n; for(int i=1;i<=n;i++){ d1[i]=d2[i]=d3[i]=INF; head[i]=-1; } for(int i=1;i >u>>v>>val; add_edge(u,v,val); add_edge(v,u,val); d[u]++;d[v]++; } if(n==1){ cout<<0; return ; } for(int i=1;i<=n;i++){ if(d[i]>1){ rt=i; break; } } dfs_d(rt,-1); for(int i=1;i<=n;i++){ up[i]=d1[i]+d2[i]; if(up[i]>=INF)up[i]=INF; } dfs_u(rt,-1); for(int i=1;i<=n;i++){ // cout< >__; while(__--){ solve(); } return 0; }



