因为边权和之前通过的人数有关,所以我们需要先一遍拓扑求出边权。
然后第二次拓扑求出dp[i]以i为起点到0的答案。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops") #include<bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10; int n,m,to[N],w[N],dp[N],res=-1,a[N],deg[N]; int dfs(int x){ if(!x) return 0; if(dp[x]) return dp[x]; return dp[x]=w[x]+dfs(to[x]); } signed main(){ cin>>n>>m; queue<int> q; for(int i=1;i<=n;i++) scanf("%lld",&to[i]),deg[to[i]]++; for(int i=1,x;i<=m;i++) scanf("%lld %lld",&a[i],&x),w[a[i]]+=x; for(int i=1;i<=n;i++) if(!deg[i]) q.push(i); while(q.size()){ int u=q.front(); q.pop(); if(--deg[to[u]]==0) q.push(to[u]); w[to[u]]+=w[u]; } for(int i=1;i<=n;i++) dfs(a[i]); for(int i=1;i<=m;i++) if(res==-1||dp[a[i]]<dp[res]||(dp[a[i]]==dp[res]&&a[i]>res)) res=a[i]; cout<<res<<' '<<dp[res]; return 0; }