「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。
这是一道20年的省赛题,难度定义为简单,但实际上还是有一些难度的。对于刷了很多dfs题的人来说,这道题应该不在话下,但是对于刚刷题起步的人来说,很难一下子有思路并做出来。
题目
原题不贴出来了,大致说一下题目意思。一共有N种作物种子,现在给你M种作物种子,然后让你用这M种作物种子得出一种我们想要的作物种子,一种作物种子可以由另外两种作物杂交得到。输入N,M,t,表示所有的作物种子,我们有的作物种子,和我们想要得到的作物种子,下面一行有N个数字表示作物生长到能杂交的日期。再下一行表示我们有的作物种子,再N行表示一种作物由另外两种作物杂交出来。最后输出要得到我们想要的种子需要的最短日子。
思路
对于我们要得到的这个种子,我们肯定第一时间想到它由哪两种种子得到,得到这两种种子,我们就可以得到结果。如何得到这两种种子,我们也如上述所说往后推即可。先不谈得到我们需要的种子最短需要多长,现在随便选一颗种子,我们得到他最短需要多少时间呢?如果这颗种子我们已经有了,那么最短时间就是0。如果这颗种子我们原先没有,那么我们需要的最短时间就是合成这颗种子的两颗种子生长的时间。如果我们所需要的两颗种子没有,那就接着往下搜索能够合成这两颗种子的作物,然后时间也要加上,如果还没有,再往下搜索。当然搜索的时间也要加上。最后得出总时间。要得出一颗种子的时间最短就是这样。、
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,k,t;
int grow[2000];
bool have[2000];
int dis[2000];
int x,a,b,c;
struct node
{
int a,b;
};
vector<node> v[2000];
int dfs(int now)
{
if(have[now])
{
return dis[now];
}
else
{
for(int i=0; i<v[now].size(); i++)
{
node p=v[now][i];
dis[now]=min(dis[now],max(dfs(p.a),dfs(p.b))+max(grow[p.a],grow[p.b]));
}
have[now]=true;
return dis[now];
}
}
int main()
{
cin>>n>>m>>k>>t;
for(int i=1; i<=n; i++)
{
cin>>grow[i];
}
memset(dis,127,sizeof(dis));
for(int i=1; i<=m; i++)
{
cin>>x;
have[x]=1;
dis[x]=0;
}
node demo;
for(int i=1; i<=k; i++)
{
cin>>a>>b>>c;
demo.a=a;
demo.b=b;
v[c].push_back(demo);
}
int ans=dfs(t);
cout<<ans<<endl;