题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805424153280512
题目大意:给你一棵树,根节点为0,每个节点都有一个权值,再给定一个数num,让你输出所有从根节点到叶子节点权值和为num的路径(输出的是权值),要按从大到小的顺序输出路径。
分析:一共才100个点,搜一下就可以了。主要是cmp函数,我用结构体存储每一条路径,cmp函数猜了一发,竟然过了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 110;
int n, m, cnt, sum, c[N], head[2 * N];
ll num, w[N];
struct node {
int count, ans[N];
node() { count = 0; }
}a[N];
struct Edge {
int to, nxt;
}edge[2 * N];
bool cmp(const node x, const node y) {
int i, j;
for(i = 0, j = 0; i < x.count, j < y.count; i++, j++) {
if(x.ans[i] > y.ans[j]) return true;
else if(x.ans[i] < y.ans[j]) return false;
}
if(i > j) return true;
return false;
}
void add(int a, int b) {
edge[cnt].to = b;
edge[cnt].nxt = head[a];
head[a] = cnt++;
}
string tostring(ll x) {
string tmp = "";
while(x) {
int mod = x % 10;
x /= 10;
tmp += (mod + '0');
}
reverse(tmp.begin(), tmp.end());
return tmp;
}
void dfs(int x, int pre, int he, int step) {
if(he > num) return ;
int flag = 1;
for(int i = head[x]; i != -1; i = edge[i].nxt) {
int j = edge[i].to;
if(j == pre) continue;
c[step] = w[j];
dfs(j, x, he + w[j], step + 1);
flag = 0;
}
if(flag && he == num) {
for(int i = 0; i < step; i++)
a[sum].ans[a[sum].count++] = c[i];
sum++;
}
}
int main() {
cnt = 0;
memset(head, -1, sizeof head);
scanf("%d %d %lld", &n, &m, &num);
for(int i = 0; i < n; i++)
scanf("%lld", &w[i]);
while(m--) {
int id, k, x;
scanf("%d %d", &id, &k);
for(int i = 1; i <= k; i++) {
scanf("%d", &x);
add(id, x);
add(x, id);
}
}
sum = 0;
c[0] = w[0];
dfs(0, -1, w[0], 1);
sort(a, a + sum, cmp);
for(int i = 0; i < sum; i++) {
for(int j = 0; j < a[i].count; j++)
printf("%d%s", a[i].ans[j], j == a[i].count - 1 ? "\n" : " ");
}
return 0;
}