代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int n, k, t;
vector<int> f[N];
int nodeStep[N];
int nodeNext[N];
bool vis[N];
stack<int> s;
bool locked[N];
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> k;
for (int j = 0; j < k; j++) {
cin >> t;
f[i].push_back(t);
}
sort(f[i].begin(), f[i].end(), greater<int>());
}
memset(nodeStep, -1, sizeof(nodeStep));
memset(nodeNext, -1, sizeof(nodeNext));
memset(vis, false, sizeof(vis));
queue<vector<int>> q;
for (int i = 0; i < n; ++i) {
//如果该节点已经走过了 说明当该节点作为头节点没有最大值
if (vis[i]) continue;
//把初始节点推入
q = queue<vector<int>>();
q.push({i});
while (!q.empty()) {
vector<int> cur = q.front();
q.pop();
int curIdx = cur[cur.size() - 1];
int step = cur.size() - 1 + nodeStep[curIdx];
if (nodeStep[curIdx] >=step && vis[curIdx]) {
for (int j = 0; j < cur.size() - 1; ++j) {
nodeStep[cur[j]] = step--;
}
continue;
}
if (f[curIdx].size() == 0) {
//无路可走记录nodeStep
for (int j = 0; j < cur.size(); j++) {
nodeStep[cur[j]] = cur.size() - j;
nodeNext[cur[j]] = (j == cur.size() - 1 ? -1 : cur[j + 1]);
}
} else {
for (auto value: f[curIdx]) {
vis[curIdx] = true;
vector<int> tmp = cur;
tmp.push_back(value);
q.push(tmp);
}
}
}
}
int idx = 0;
for (int i = 0; i < n; ++i) {
if (nodeStep[i] > nodeStep[idx]) idx = i;
}
cout << nodeStep[idx] << endl;
cout << idx;
idx = nodeNext[idx];
for (; idx != -1; idx = nodeNext[idx]) {
cout << " " << idx;
}
return 0;
}
前置
for (int i = 0; i < n; i++) {
cin >> k;
for (int j = 0; j < k; j++) {
cin >> t;
f[i].push_back(t);
}
sort(f[i].begin(), f[i].end(), greater<int>());
}
采用了降序排列
为什么 因为待会儿bfs可以重写覆盖
bfs 是队列 ,把最大的数写入 nodeStep ,nodeNext 最小的可以覆盖;
就是先让降序的病原体先去送炮灰 ,一个一个送 剩下来的就是符合题目要求的小数了
大纲
有N个病原体 循环N次 对每个病原体的突变进行BFS
for (int i = 0; i < n; ++i) {
q = queue<vector<int>>();
q.push({i});
while (!q.empty()) {
}
}
队列用vector 储存变异链路
记忆化
vector<int> f[N]; //保存输入
int nodeStep[N]; //保存最大步数
int nodeNext[N]; //保存最大步数的路径
bool vis[N]; //保存是否访问过
vis解释: 我们上面提到过 采用n个bfs ,这样会很浪费资源和时间
因此我用vis记录已经对第n个病原体遍历过了 待会儿解释
实行记忆化
if (nodeStep[curIdx] >=step && vis[curIdx]) {
for (int j = 0; j < cur.size() - 1; ++j) {
nodeStep[cur[j]] = step--;
}
continue;
}
因为如果vis[i]=true 说明已经bfs了 他的解是最优的了 所以我们只要拼接上去就好了 然后continue 跳过循环