題目鏈接:http://pat.zju.edu.cn/contests/pat-a-practise/1053
同一類型:路徑長度、保存與給定值相同的路徑長度、記錄一定深度的路徑、記錄節點號/值。
// 採用鄰接表表示樹
// 用vector存儲路徑
// 路徑不止1一條,需用vector< vector<int> >存儲所有路徑
// 輸入時建樹
// 得到一個節點的所有子節點後,進行排序:按權值
// dfs遍歷,葉節點處判斷。返回上一層時,去掉path中的權值
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <limits.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define SIZE 100+10
using namespace std;
struct Node
{
int key;
vector<int> child;
};
int N, M, S;
vector<Node> Tree;
vector<int> path;
vector<vector<int> > ans;
bool cmp(int a, int b)
{
return Tree[a].key > Tree[b].key;
}
void Input()
{
scanf("%d%d%d", &N, &M, &S);
int i;
for(i = 0; i < N; i++)
{
Node t;
scanf("%d", &t.key);
Tree.push_back(t);
}
// input and creating tree
for(i = 0; i < M; i++)
{
int id, num;
scanf("%d%d", &id, &num);
while(num-- > 0)
{
int child_id;
scanf("%d", &child_id);
Tree[id].child.push_back(child_id);
}
//sorting
sort(Tree[id].child.begin(), Tree[id].child.end(), cmp);
}
return ;
}
void dfs(int id, int sum)
{
path.push_back(Tree[id].key);
sum = sum + Tree[id].key;
// leaf
if(Tree[id].child.size() == 0)
{
if(sum == S)
{
ans.push_back(path);
return ;
}// 得到一條路徑
else
{
return ;
}
}
else
{
if(sum < S)
{
for(int j=0; j<Tree[id].child.size(); j++)
{
int next = Tree[id].child[j];
dfs(next, sum);
path.pop_back();//當前節點退出路徑
}
return ;//所有子節點遍歷完成,返回
}
else
{
return ;//非葉節點的和已經大於等於S,返回
}
}
}
// 構造樹後輸出結果,驗證是否正確
void Output()
{
for(int i=0; i < Tree.size(); i++)
{
printf("%02d:", i);
for(int j=0; j<Tree[i].child.size(); j++)
{
printf("%d ", Tree[i].child[j]);
}
printf("\n");
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("E:\\in.txt", "r", stdin);
#endif
Input();
// Output();
int sum = 0;
dfs(0, sum);
// output
for(int i=0; i < ans.size(); i++)
{
for(int j=0; j<ans[i].size()-1; j++)
{
printf("%d ", ans[i][j]);
}
printf("%d\n", ans[i][ans[i].size()-1]);
}
return 0;
}