蓝桥杯2020省赛-作物杂交C++dfs做法

题目描述:

作物杂交是作物栽培中重要的一步。已知有 NN 种作物 (编号 11 至 NN ),第 ii 种作物从播种到成熟的时间为 T_iTi​。作物之间两两可以进行杂交,杂交时间取两种中时间较长的一方。如作物 A 种植时间为 5 天,作物 B 种植时间为 7 天,则 AB 杂交花费的时间为 7 天。作物杂交会产生固定的作物,新产生的作物仍然属于 NN 种作物中的一种。

初始时,拥有其中 MM 种作物的种子 (数量无限,可以支持多次杂交)。同时可以进行多个杂交过程。求问对于给定的目标种子,最少需要多少天能够得到。

如存在 4 种作物 ABCD,各自的成熟时间为 5 天、7 天、3 天、8 天。初始拥有 AB 两种作物的种子,目标种子为 D,已知杂交情况为 A × B → C,A × C → D。则最短的杂交过程为:

第 1 天到第 7 天 (作物 B 的时间),A × B → C。

第 8 天到第 12 天 (作物 A 的时间),A × C → D。

花费 12 天得到作物 D 的种子。

输入描述:

输入的第 1 行包含 4 个整数 N, M, K, TN,M,K,T,NN 表示作物种类总数 (编号 11 至 NN),MM 表示初始拥有的作物种子类型数量,KK 表示可以杂交的方案数,TT 表示目标种子的编号。

第 2 行包含 NN 个整数,其中第 ii 个整数表示第 ii 种作物的种植时间 T_i\ (1 \leq T_i \leq 100)Ti​ (1≤Ti​≤100)。

第 3 行包含 MM 个整数,分别表示已拥有的种子类型 K_j\ (1 \leq K_j \leq M)Kj​ (1≤Kj​≤M),K_jKj​ 两两不同。

第 4 至 KK + 3 行,每行包含 3 个整数 A, B,CA,B,C,表示第 AA 类作物和第 BB 类作物杂交可以获得第 CC 类作物的种子。

其中, N1≤N≤2000,2≤M≤N,1≤K≤105,1≤T≤N, 保证目标种子一定可以通过杂交得到。

输出描述:

输出一个整数,表示得到目标种子的最短杂交时间。

样例:

6 2 4 6

5 3 4 6 4 9

1 2

1 2 3

1 3 4

2 3 5

4 5 6

 解决方案:

该题的难点在于如何根据题目的输入进行建图。这里采用以杂交植物作为目标节点的建图方法建立有向图。

蓝桥杯2020省赛-作物杂交C++dfs做法_第1张图片

 采用邻接链表的表示方法,其中将顶点定义为杂交方案组成的结构体。代码如下:

#include 
#include
#include
#include
using namespace std;
const int N = 100010;
const int INF = 0x3f3f3f3f;

int h[N],ne[N],idx; //邻接链表
int n,m,k,t; 
int Time[N];   //表示每种作物的生长时间
int color[N]; //标记是否已出现
int g[N]; //表示总杂交时间
//邻接表中存储的应是作物的杂交方案
struct E{
  int a,b;
}e[N];
void add(int a,int b,int c){
  
  e[idx].a=b;e[idx].b=c;
  ne[idx] = h[a];
  h[a] = idx++;
}                            //邻接表的插入操作
int dfs(int u){
  if(color[u]) return g[u]; //目标结点已经被访问过说明已计算过时间,直接返回
  for(int i=h[u];i!=-1;i=ne[i]){
    E j=e[i];  
    g[u] = min(g[u],max(Time[j.a],Time[j.b])+max(dfs(j.a),dfs(j.b)));//递归计算杂交时间,两种作物的生长时间最大值和杂交时间最大值
  }
  color[u]=true;//标记被访问
  return g[u];
}
int main()
{
  // 请在此输入您的代码
  ios::sync_with_stdio(false);
  memset(h,-1,sizeof h);   //初始化邻接表
  memset(g,INF,sizeof g); //将初始杂交时间设为无穷大
  cin>>n>>m>>k>>t;
  for(int i=1;i<=n;i++){
    cin>>Time[i];
  }  //输入时间
  for(int i=0;i>temp;
    color[temp]=1;
    g[temp]=0;  //已有作物杂交时间为0
  }
  for(int i=1;i<=k;i++){
    int a,b,c;
    cin>>a>>b>>c;
    add(c,a,b);
  
  } //建立邻接表
  dfs(t);
  cout<

你可能感兴趣的:(蓝桥杯,c++,深度优先)