【1053 30 dfs 树的路径和】 Path of Equal Weight

传送门

题意

给定 \(n\) 个节点,以及每个节点的权重 \(w_{i}\)\(m\) 个节点的出边关系,目标值 \(k\) ,每个关系为 \(id,k,id_{1},\dots,id_{k}\) ,即 \(id\) 节点的 \(k\) 条边的终点,求树中所有满足权重和为 \(k\) 的路径,这里指的是以根为起点,叶节点为终点的,输出路径中的每个点的权重,如果有多条,按照类似字典序的比较方式对不同路径按照从大到小顺序输出

数据范围

\(n\leq 100\)

题解

  • 用存边的方式将图存储下来,利用结构体同时存储节点的权重 \(w_{i}\)
  • 因为是按层遍历的,将某一节点的所有连点按照权重从大到小排序,输出时即为要求的顺序
  • dfs 求所有的路径,两个剪枝
    • 和大于要求值的时候剪枝
    • 和等于要求值但是当前节点不是叶子节点
  • 存取每个节点的上个节点,输出的时候根据这个找到对应权重输出即可

Code

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define rep(i,a,n) for(int i=a;i<n;i++)
#define sz size
const int N=110;
vector<int>pre;
int n,m,k; 
struct node{
	int w;
	vector<int>edge;
};
vector<node>a;
bool cmp(int x,int y){ return a[x].w>a[y].w;}

void dfs(int u,int sum){
	if(sum>k) return;
	if(sum==k){
		if(a[u].edge.sz()) return;
		vector<int>path;
		int p=u;
		path.pb(u);
		while(p!=0){
			p=pre[p];
			path.pb(p);
		}
		reverse(path.begin(),path.end());
		rep(i,0,path.sz()) {
			if(i==path.sz()-1) printf("%d\n",a[path[i]].w);
			else printf("%d ",a[path[i]].w);
		}
	}
	
	
	rep(i,0,a[u].edge.sz()){
		int v=a[u].edge[i];
		pre[v]=u;
		dfs(v,sum+a[v].w);
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&k);
	a.resize(n); pre.resize(n);
	rep(i,0,n) scanf("%d",&a[i].w);
	while(m--){
		int id,p; scanf("%d%d",&id,&p);
		a[id].edge.resize(p);
		rep(i,0,p)  scanf("%d",&a[id].edge[i]);
		sort(a[id].edge.begin(),a[id].edge.end(),cmp);
	}
	dfs(0,a[0].w);
}
posted @ 2021-02-24 20:04  Hyx'  阅读(64)  评论(0)    收藏  举报