本题最重要的点:
由于最后的输出需要按权值从大到小排序,因此在读入时要事先对每个结点的子节点vector进行排序(即对vector中的结点按权值从大到小排序),这样在遍历时就会优先遍历到权值大的子结点. 开始没有做这个预处理,导致最后难以对获取到的数据进行排序.
注意点:cmp()见下.
通过DFS寻找到路径上权值总和=s的所有叶子结点并存储下来,然后通过叶子结点向上寻找其父结点.比较繁琐.
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=1010;
struct node{int father;int weight;vector<int> child;
}nodes[maxn];
vector<int> leaf;
int s,num=0;
void dfs(int root,int w){if(nodes[root].child.size()==0){if(w==s){leaf.push_back(root);}return;}for(int i=0;i<nodes[root].child.size();i++){dfs(nodes[root].child[i],w+nodes[nodes[root].child[i]].weight);}
}
bool cmp(int a,int b){return nodes[a].weight>nodes[b].weight; //此处不能通过if判断两者不等后再return,会导致最后一个测试点发生段错误(因为当数组中所有数均相等时,if语句将永远不为真)
}
int main(){#ifdef ONLINE_JUDGE#elsefreopen("1.txt","r",stdin);#endifint n,m,id,k,t[maxn];scanf("%d%d%d",&n,&m,&s);for(int i=0;i<n;i++){scanf("%d",&nodes[i].weight);}for(int i=0;i<m;i++){scanf("%d%d",&id,&k);for(int j=0;j<k;j++){scanf("%d",&t[j]);}sort(t,t+k,cmp);for(int j=0;j<k;j++){nodes[id].child.push_back(t[j]);nodes[t[j]].father=id;}}nodes[0].father=-1;dfs(0,nodes[0].weight);vector<int> res;for(int i=0;i<leaf.size();i++){int now=leaf[i];while(now!=-1){res.push_back(nodes[now].weight);now=nodes[now].father;}for(int j=res.size()-1;j>=0;j--){printf("%d",res[j]);if(j!=0){printf(" ");}}printf("\n");res.clear(); }return 0;
}
DFS同时将数据输出.
//用数组存放路径,利用idx更新下标
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=1010;
int s,path[maxn];
struct node{int weight;vector<int> child;
}nodes[maxn];
bool cmp(int a,int b){return nodes[a].weight>nodes[b].weight; //注意:比较的是结点的权值,而不是结点标号
}
void DFS(int root,int idx,int w){if(w>s){return;}else if(w==s){if(nodes[root].child.size()==0){path[idx]=root;for(int i=0;i<=idx;i++){printf("%d",nodes[path[i]].weight);if(i!=idx){printf(" ");}}printf("\n");}return;}else{path[idx]=root;}for(int i=0;i<nodes[root].child.size();i++){DFS(nodes[root].child[i],idx+1,w+nodes[nodes[root].child[i]].weight);}
}
int main(){#ifdef ONLINE_JUDGE#elsefreopen("1.txt","r",stdin);#endifint n,m,id,k,t[maxn];scanf("%d%d%d",&n,&m,&s);for(int i=0;i<n;i++){scanf("%d",&nodes[i].weight);}for(int i=0;i<m;i++){scanf("%d%d",&id,&k);for(int j=0;j<k;j++){scanf("%d",&t[j]);}sort(t,t+k,cmp);for(int j=0;j<k;j++){nodes[id].child.push_back(t[j]);}}DFS(0,0,nodes[0].weight);return 0;
}
//用vector存放路径,利用push,pop操作.
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=1010;
int s;
struct node{int weight;vector<int> child;
}nodes[maxn];
vector<int> path;
bool cmp(int a,int b){return nodes[a].weight>nodes[b].weight; //注意:比较的是结点的权值,而不是结点标号
}
void DFS(int root,int w){if(w>s){return;}else if(w==s){if(nodes[root].child.size()==0){for(int i=0;i<path.size();i++){printf("%d",nodes[path[i]].weight);if(i!=path.size()-1){printf(" ");}}printf("\n");}return;}for(int i=0;i<nodes[root].child.size();i++){path.push_back(nodes[root].child[i]);DFS(nodes[root].child[i],w+nodes[nodes[root].child[i]].weight);path.pop_back();}
}
int main(){#ifdef ONLINE_JUDGE#elsefreopen("1.txt","r",stdin);#endifint n,m,id,k,t[maxn];scanf("%d%d%d",&n,&m,&s);for(int i=0;i<n;i++){scanf("%d",&nodes[i].weight);}for(int i=0;i<m;i++){scanf("%d%d",&id,&k);for(int j=0;j<k;j++){scanf("%d",&t[j]);}sort(t,t+k,cmp);for(int j=0;j<k;j++){nodes[id].child.push_back(t[j]);}}path.push_back(0);DFS(0,nodes[0].weight);return 0;
}