题意:
给出一个树的结构,每个节点有个权值,求从根到叶子节点, 总和为s的所有路径。
思路:
直接用father来存储树结构了, 从每个叶子节点不断向上回溯到根节点,即可找到所有和为s路径。
这样得到的是反的序列,故用 reverse(pathv.begin(),pathv.end()); 进行vector翻转。
确定输出顺序时,要进行sort,cmp函数如下:
bool cmp(vector<int> &v1, vector<int> &v2)//注意:本函数的参数的类型一定要与vector中元素的类型一致
{
int i,j;
int n1=v1.size(),n2=v2.size();
int n = n1<n2?n1:n2;
for(i=0;i<n;i++)
{
if(v1[i]>v2[i])
return true;
else if(v1[i]<v2[i])
return false;
}
if(n1>n2 )
return true;
else return false;
}
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<map>
using namespace std;
#define INF 99999999
#define M 1000
bool cmp(vector<int> &v1, vector<int> &v2)//注意:本函数的参数的类型一定要与vector中元素的类型一致
{
int i,j;
int n1=v1.size(),n2=v2.size();
int n = n1<n2?n1:n2;
for(i=0;i<n;i++)
{
if(v1[i]>v2[i])
return true;
else if(v1[i]<v2[i])
return false;
}
if(n1>n2 )
return true;
else return false;
}
//start 16:28
//stop 17:25
int main(){
int nonleaf[200],w[200],father[200];
int i,j,cid,m,n,s,id,cn;
memset(nonleaf,0,sizeof(nonleaf));
scanf("%d%d%d",&n,&m,&s);
for(i=0;i<n;i++)
scanf("%d",&w[i]);
for(i=0;i<m;i++)
{
scanf("%d%d",&id,&cn);
nonleaf[id]=1;
for(j=0;j<cn;j++)
{
scanf("%d",&cid);
father[cid] = id;
}
}
father[0] = -1;
int sum=0;
int p;
vector<int> pathv;
vector< vector<int> > ansv;
for(i=0;i<n;i++)
{
if(!nonleaf[i])
{
pathv.clear();
p=i;
sum=0;
while(p != -1)
{
sum += w[p];
pathv.push_back(w[p]);
p = father[p];
}
if(sum==s)
{
reverse(pathv.begin(),pathv.end());
ansv.push_back(pathv);
}
}
}
std::sort(ansv.begin(),ansv.end(),cmp);
for(i=0;i<ansv.size();i++)
{
for(j=0;j<ansv[i].size();j++)
{
printf("%d",ansv[i][j]);
if(j!=ansv[i].size()-1)
cout<<" ";
else cout<<endl;
}
}
}