P3125 [USACO15OPEN]Bessie's Birthday Buffet S题解
大佬们用什么 SPFA 和 DP,我这个蒟蒻根本看不懂,既然看不懂,就来水一篇简单易懂的 BFS + DP 的题解吧!
题意简化:
有
之所以这题使用 BFS,是因为它的每一个点不是与其他点相通的,并且只会吃比之前吃的草更好吃,即能量更多的草。
所以我们只需要用 BFS 遍历一遍,记录每片草地能从哪些草地过来,这是 BFS 要做的事情。
接下来,就来到 DP 的部分了。
首先给出递推式:
先解释一下式子中变量的意思,
然后来解释一下这个式子,通过推导,可以发现从第 d[i][j]*e 的能量值,于是这个式子就被我们推导出来了。
完整代码:
#include<bits/stdc++.h>
using namespace std;
int n,e,vis[1010][1010],d[1010][1010],f[1010];
struct cow{
int id,v;
}a[1010];
vector<int>g[1010];
void bfs(int b){
queue<int>q;
q.push(b);
vis[b][b]=1;
d[b][b]=0;
while(q.size()){
int front = q.front();
q.pop();
for(int i=0;i<g[front].size();i++){
int t=g[front][i];
if(!vis[b][t]){
vis[b][t]=1;
d[b][t]=d[b][front]+1;
q.push(t);
}
}
}
}
bool cmp(cow A,cow B){
return A.v<B.v;
}
int main(){
cin>>n>>e;
for(int i=1;i<=n;i++){
cin>>a[i].v;
a[i].id=i;
int t;
cin>>t;
for(int j=1;j<=t;j++){
int temp;
cin>>temp;
g[i].push_back(temp);
}
}
for(int i=1;i<=n;i++)
bfs(i);
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
f[i]=a[i].v;
for(int j=1;j<i;j++){
if(vis[a[i].id][a[j].id])
f[i]=max(f[i],f[j]-d[a[i].id][a[j].id]*e+a[i].v);
}
}
int ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,f[i]);
cout<<ans;
return 0;
}