spfa+dp
脑洞好大
这是一个dp,可惜有环,不能直接记忆化搜索,但是我们用spfa优化一下,如果一个点的dp值被更新,那么他的前继也要重新入队进行dp,因为前继是由后继更新的
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 200010; struct monster { ll s, k; } m[N]; int n; queue<int> q; vector<int> G[N], rev[N]; ll dp[N]; int vis[N]; int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) { int u, x; scanf("%lld%lld%d", &m[i].s, &m[i].k, &x); while(x--) { scanf("%d", &u); G[i].push_back(u); rev[u].push_back(i); } } queue<int> q; for(int i = 1; i <= n; ++i) q.push(i), vis[i] = 1, dp[i] = m[i].k; while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; ll sum = m[u].s; for(int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; sum += dp[v]; } if(sum >= dp[u]) continue; dp[u] = sum; for(int i = 0; i < rev[u].size(); ++i) { int v = rev[u][i]; if(!vis[v]) { vis[v] = 1; q.push(v); } } } printf("%lld ", dp[1]); return 0; }