蓝桥杯刷题——作物杂交(搜索)

363 阅读2分钟

「这是我参与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;