L2-2 病毒溯源 (25 分)
DFS+路径优化存储
题目
代码
#include "bits/stdc++.h"
using namespace std;
const int G = 10000;
vector<int> Map[G]; //用一个二维动态数组来存图 (邻接表)
vector<int> res; //用来存放最终答案路径
//判断是否要优化res
bool check(vector<int> &v){
if(v.size() < res.size()) return true; //v容器的长度比res短,证明v容器的路径比res的路径更优
else if(v.size() == res.size()){
for(int i=0;i<v.size();i++){ //满足题目中 如果最长链不唯一,则输出最小序列 的要求
if(v[i]!=res[i] && v[i]<res[i]) return true;
if(v[i]!=res[i] && v[i]>res[i]) return false;
}
return false;
} else return false;
}
//now 是当前节点 v 是当前路径
void dfs(int now,vector<int> &v){
for (int i = 0; i < Map[now].size(); ++i) {
v.push_back(Map[now][i]);
if(check(v)) res = v; //贪心思想,边存边优化
dfs(Map[now][i],v);
v.pop_back();
}
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int root;
int N;
cin>>N;
int sum = 0;
int Sum = (0+N-1)*N/2; //编号可以看成一个首项为0,末项为n-1,公差为1的等差数列,这里简单求个和,用来找根节点(病毒源头)
for (int i = 0; i < N; ++i) {
int n;
cin>>n;
while (n--){
int a;
cin>>a; //这里出现的病毒一定是变异病毒
Map[i].push_back(a); //存个图
sum+=a; //将所有变异病毒的编号加起来
}
}
root = Sum-sum; //简单求个根节点,好吧。
vector<int>v;
//把根节点存起来
v.push_back(root);
res.push_back(root);
dfs(root,v); //暴力搜就完了,优化个屁!
cout<<res.size()<<endl;
for (int i = 0; i < res.size(); ++i) {
if(i) cout<<" ";
cout<<res[i];
}
return 0;
}
题解
本题难点:
1.判断根节点位置;
2.路径存储;
3.优化存储的路径
解决方法
1.由于本题说 题目保证病毒源头有且仅有一个。
所以,所有变异的病毒统统都不是根节点,所以将所有病毒的编号加起来 int Sum = (0+N-1)*N/2;
减去变异病毒的编号就是病毒源头的编号 root
2. 对于路径的存储,我们可以在dfs的时候传入一个容器 V
用来存储当前的路径 dfs(int now, vectoe<int>&v); //注意这里要传入容器的引用,由于dfs属于递归函数会调用多次dfs函数,这里若是不传引用的话,系统内部会复制出来很多容器V,最终会报内存超限的错误,而传引用,每次只对当前的容器V进行操作,减少内存的使用
3.优化存储路径,我们可以定义一个保存最终最优解的容器 res
,对于对这个容器维护的问题,在每一次更新我们的容器 V
的时候,就可以判断 res
是否可以进行优化,其判断函数如下
bool check(vector<int>& v){
if(v.size() < res.size()) return true; //v容器的长度比res短,证明v容器的路径比res的路径更优
else if(v.size() == res.size()){
for(int i=0;i<v.size();i++){ //满足题目中 如果最长链不唯一,则输出最小序列 的要求
if(v[i]!=res[i] && v[i]<res[i]) return true;
if(v[i]!=res[i] && v[i]>res[i]) return false;
}
return false;
} else return false;
}
当 V
中的路径比 res
中的路径更优时,则将 res
更新成 V
的当前路径if(check(v)) res = v;