在写这道题的时候出现了测试点5未通过的情况,以下是初次尝试的代码,写的有些啰嗦,反正主要用了dfs的方法写的。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct leaf{
vector<int>path;
};
vector<leaf> leafs;
int path[105]={0},n,m,s,k,temp,id;
long long weight[105]={0} ;
vector<int> son[105];
bool cmp(leaf a,leaf b){//发生段错误或运行时错误,这里出问题了
for(int i=0;i<a.path.size() && i<b.path.size();i++){
if(a.path[i]!=b.path[i])return a.path[i]>b.path[i];
}
// return a.path.size()>b.path.size();//为什么?//这不管是什么都可以通过
// return true;
}
void dfs(int index,int high,long long sum){
path[high-1]=weight[index];
if(sum>s)return ;
if(son[index].size()==0){
if(sum!=s)return ;
leaf l;
for(int i=0;i<high;i++){
l.path.push_back(path[i]);
}
leafs.push_back(l);
return ;
}
for(int i=0;i<son[index].size();i++){
dfs(son[index][i],high+1,sum+weight[son[index][i]]);
}
}
int main(){
cin>>n>>m>>s;
for(int i=0;i<n;i++) cin>>weight[i];
for(int i=0;i<m;i++){
cin>>id>>k;
for(int j=0;j<k;j++){
cin>>temp;
son[id].push_back(temp);
}
}
dfs(0,1,weight[0]);
sort(leafs.begin(),leafs.end(),cmp);
for(int i=0;i<leafs.size();i++){
for(int j=0;j<leafs[i].path.size();j++){
if(j!=0)printf(" ");
printf("%d",leafs[i].path[j]);
}
printf("\n");
}
return 0;
}
然后找了很久发现是cmp比较函数出了问题,当leafs中所有元素都相同时就会报错,以下是模拟测试点5的输入:(其实只要leafs数组中超过17个相等的元素就会报错了)
20 1 20
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
00 19 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
接着我找到了一篇文章,讲的是为什么自建的cmp函数放到sort函数会报错的原因:
C++中使用std::sort自定义排序规则时要注意的崩溃问题_std::sort 崩溃-优快云博客
简而言之说的就是如果cmp(a,b)==true 那么一定要cmp(b,a)==false;
而cmp(a,b)==false 且cmp(b,a)==false 的情况也是可以的;
但是 cmp(a,b)==true 且 cmp(b,a)==true 的情况是错误的。
原理是sort函数中有一段__unguarded_linear_insert的函数只有当cmp(a,a+1)==false 时才停下来。
所以正确的改动很简单,在cmp里面最后加上return false;就可以了(一定不能return true;!!!)
以下是ac的代码(就改动一个点就不用看啦)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct leaf{
vector<int>path;
};
vector<leaf> leafs;
int path[105]={0},n,m,s,k,temp,id;
long long weight[105]={0} ;
vector<int> son[105];
bool cmp(leaf a,leaf b){
for(int i=0;i<a.path.size() && i<b.path.size();i++){
if(a.path[i]!=b.path[i]){
return a.path[i]>b.path[i];
}
}
return false;
}
void dfs(int index,int high,long long sum){
path[high-1]=weight[index];
if(sum>s)return ;
if(son[index].size()==0){
if(sum!=s)return ;
leaf l;
for(int i=0;i<high;i++){
l.path.push_back(path[i]);
}
leafs.push_back(l);
return ;
}
for(int i=0;i<son[index].size();i++){
dfs(son[index][i],high+1,sum+weight[son[index][i]]);
}
}
int main(){
cin>>n>>m>>s;
for(int i=0;i<n;i++) cin>>weight[i];
for(int i=0;i<m;i++){
cin>>id>>k;
for(int j=0;j<k;j++){
cin>>temp;
son[id].push_back(temp);
}
}
dfs(0,1,weight[0]);
sort(leafs.begin(),leafs.end(),cmp);
for(int i=0;i<leafs.size();i++){
for(int j=0;j<leafs[i].path.size();j++){
if(j!=0)printf(" ");
printf("%d",leafs[i].path[j]);
}
printf("\n");
}
return 0;
}
之后再碰到所有元素相同的情况要记得cmp函数在cmp(a,a)的时候返回false就可以了。