本題最重要的點:
由於最後的輸出需要按權值從大到小排序,因此在讀入時要事先對每個結點的子節點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
#else
freopen("1.txt","r",stdin);
#endif
int 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
#else
freopen("1.txt","r",stdin);
#endif
int 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
#else
freopen("1.txt","r",stdin);
#endif
int 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;
}