由于最后输出的路径排序是降序输出,相当于dfs的时候应该先遍历w最大的子节点。
链式前向星的遍历是从最后add的子节点开始,最后添加的应该是w最大的子节点,
因此建树的时候先对child按w从小到大排序,然后再add建边。
水题一个,不多说了。
#include <iostream> #include <algorithm> #include <cstdio> #include <string.h> using namespace std; const int maxn=105; int head[maxn]; int tot=0; int path[maxn]; struct Node{ int id; int w; bool operator<(const Node tmp)const{ return w<tmp.w; } }node[maxn]; struct Edge{ int to; int next; }edge[maxn]; void init(){ memset(head,-1,sizeof(head)); tot=0; } void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } void dfs(int u,int layer,int sum,int s){ if(sum>s) return; if(sum==s){ if(head[u]!=-1) return; printf("%d",path[0]); for(int i=1;i<=layer;i++){ printf(" %d",path[i]); } printf(" "); return; } for(int k=head[u];k!=-1;k=edge[k].next){ int v=edge[k].to; path[layer+1]=node[v].w; dfs(v,layer+1,sum+node[v].w,s); } } int main() { int n,m; int s; //顶多100个点,wi最大也只有1000,所以S的范围肯定不会超过100000,int即可 int w; init(); scanf("%d %d %d",&n,&m,&s); for(int i=0;i<n;i++){ scanf("%d",&w); node[i].id=i; node[i].w=w; } int id,k,child; Node tmp[maxn]; for(int i=0;i<m;i++){ scanf("%d %d",&id,&k); for(int j=0;j<k;j++){ scanf("%d",&child); tmp[j]=node[child]; } //因为遍历的时候是从最后add的边开始,所以先将child按w从小到大排序 //这样dfs的时候就会先访问w最大的节点 sort(tmp,tmp+k); for(int j=0;j<k;j++){ add(id,tmp[j].id); } } path[0]=node[0].w; dfs(0,0,node[0].w,s); return 0; }