作物杂交
题目描述
作物杂交是作物栽培中重要的一步。已知有 N 种作物 (编号 1至 N ),第 i 种作物从播种到成熟的时间为 Ti 。作物之间两两可以进行杂交,杂交时间取两种中时间较长的一方。如作物 A 种植时间为 5 天,作物 B 种植时间为 7 天,则 A B 杂交花费的时间为 7 天。作物杂交会产生固定的作物,新产生的作物仍然属于 N 种作物中的一种。
初始时,拥有其中 M 种作物的种子 (数量无限,可以支持多次杂交)。同时可以进行多个杂交过程。求问对于给定的目标种子,最少需要多少天能够得到。
如存在 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 的种子。
C++
#include <iostream> using namespace std; const int MAXN = 2000+5; int n, m, k, goal; int t[MAXN]; bool have_k[MAXN]; int zajiao[MAXN][MAXN]; int limit_time; struct father { int num; int u[MAXN]; int v[MAXN]; int limtime; }fa[MAXN]; void swap(int& a, int& b) { int tep = a; a = b; b = tep; } void input() { //N,M,K,T, //N 表示作物种类总数 (编号 11 至 N), //M 表示初始拥有的作物种子类型数量, //K 表示可以杂交的方案数,T 表示目标种子的编号。 cin >> n >> m >> k >> goal; for (int i = 1; i <= n; i++) cin >> t[i]; for (int i = 1; i <= m; i++) { int z; cin >> z; have_k[z] = true; } for (int i = 1; i <= k; i++) { int u, v, w; cin >> u >> v >> w; zajiao[u][v] = zajiao[v][u] = w; int tep = ++fa[w].num; if (t[u] < t[v])swap(u, v); fa[w].u[tep] = u; fa[w].v[tep] = v; } } bool dfs(int x) { if (fa[x].num == 0)return false; for (int i = 1; i <= fa[x].num; i++) { int v = fa[x].v[i]; int u = fa[x].u[i]; if (!have_k[u]) { if (!dfs(u))continue; } if (!have_k[v]) { if (!dfs(v))continue; } if (!fa[x].limtime) fa[x].limtime = max(fa[u].limtime, fa[v].limtime) + max(t[u], t[v]); else fa[x].limtime = min(fa[x].limtime, max(fa[u].limtime, fa[v].limtime) + max(t[u], t[v])); } have_k[x] = true; return true; } int main() { input(); dfs(goal); cout << fa[goal].limtime; return 0; }