【BZOJ3875】【Ahoi2014&Jsoi2014】骑士游戏(SPFA+DP)
简单题
如果我们把分裂看成连边
那么可以得到方程:
跑就可以了
然而显然会构成正环,然后咕咕
考虑到如果我们更新了一个点,那么这个点的所有父亲(不是很准确,大概意思就是这个)
都会因此更新答案
那在把所有父亲也加到队列里跑就可以了
如果被卡用堆优化就可以了
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
char ch=getchar();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res*f;
}
const int N=200005;
int n,vis[N];
int s[N],f[N];
queue<int> q;
vector<int> e1[N],e2[N];
signed main(){
n=read();
for(int i=1;i<=n;i++){
s[i]=read(),f[i]=read();
int siz=read();
for(int j=1;j<=siz;j++){
int v=read();
e1[i].push_back(v),e2[v].push_back(i);
}
q.push(i),vis[i]=1;
}
while(!q.empty()){
int u=q.front();q.pop(),vis[u]=0;
int tmp=s[u];
for(int i=0;i<e1[u].size();i++){
int v=e1[u][i];tmp+=f[v];
}
if(f[u]<=tmp)continue;f[u]=tmp;
for(int i=0;i<e2[u].size();i++){
int v=e2[u][i];
if(!vis[v]){
q.push(v),vis[v]=1;
}
}
}
cout<<f[1];
}