1053. Path of Equal Weight (30)

来源:互联网 发布:手机淘宝客推广软件 编辑:程序博客网 时间:2024/06/13 23:03

题目详情:https://www.patest.cn/contests/pat-a-practise/1053

提交:
这里写图片描述

提交代码:

#include <iostream>#include <string.h>#include <vector>#include <algorithm>using namespace std;#define N 110#define INF 0x3f3f3f3ftypedef struct Node{    int vertex;    int weight;}Node;//用来存储树,注意不是二叉树 vector<int> child[N];bool isLeaf[N]; //标记是否为叶子节点,如果是叶子节点则为true int n,m,weight[N],s,path[N];//weight[]记录各节点的点权,path[]记录各节点的父亲节点,根节点的path[]值为-1 bool compareTo( Node n1,Node n2 )  //定义比较函数,从小到大进行排序 {    if( n1.weight < n2.weight )        return true;    else        return false;   }void printWeight( int vertex )  //输出路径上的点权, {    while( path[vertex] != -1 )    {        printWeight(path[vertex]);          cout<<" "<<weight[vertex]; //控制输出         return ;    }    cout<<weight[vertex];}void DFS( int root,int W ){   //这是一棵树,不需要标记visit[]数组    for( int i=child[root].size()-1;i>=0;--i )  //访问孩子节点,从权值最大的节点开始     {   //cout<<"will visit "<<child[root][i]<<endl;        W = W+weight[ child[root][i] ]; //跟踪路径上的权变化,马上要递归(加上该节点的权)         DFS( child[root][i],W );        W = W-weight[ child[root][i] ]; //跟踪路径上的权变化,递归结束(要返回上一层的节点),减去当前的节点的点权     }    if( W == s && isLeaf[root] == true ) //如果有某一条路径的权等于s且为叶子节点,则输出该条路径     {        printWeight(root);        cout<<endl;    }   }int main(){    cin>>n>>m>>s;    for( int i=0;i<n;++i )        cin>>weight[i];    memset(isLeaf,true,sizeof(isLeaf)); //置     for( int i=0;i<m;++i )    {        int father,num,temp[N],j,kid;        Node node[N];        cin>>father>>num;        isLeaf[father] = false; //标记为非叶子节点         for( j=0;j<num;++j )        {            cin>>kid; //输入孩子节点的编号            path[kid] = father; //存储该节点的父亲             node[j].weight = weight[kid]; //将孩子节点的点权存到node[]数组             node[j].vertex = kid;         //存储孩子节点的权值,防止排序后节点编号信息丢失         }        //排序(从小到大),所以用结构体存储 .其中第二个参数(即node+J)是尾地址的下一个地址         sort(node,node+j,compareTo);          for( int k=0;k<num;++k )        {   //按照孩子节点的权值从小到大依次插入             child[father].push_back(node[k].vertex);        }    }    path[0] = -1;    //DFS函数之前的初始化操作    int root  = 0,W = weight[root];    DFS(root,W);//根节点编号为0,从根节点开始    return 0;}

本题思想:把输入的孩子节点按照权值进行排序,进行深度优先搜索的时候,从最后的孩子节点开始,这样就可以控制路径”大”的最前。另外设置一个跟踪路径权值的变量,本题中是W(大写),进行判断。
好像也不是什么思想,跟没说似的。代码中重要的部分都加了注释。

这道题不错,我从中学到了很多的东西,包括:
1、sort(begin,end,function)中的第二个参数是最后一个待排序的下一个地址,用数学表示就是[begin,end),举个例子,int num[100],sort(num,num+100)而不是sort(num,num+99),虽然最后一个数字的地址是num+99

2、控制输入输出,一开始的printWeight()函数如下:

void printWeight( int vertex,int start )  //没有控制输入输出 {    while( path[vertex] != -1 )    {        printWeight(path[vertex],start);  //没有改变值         if( vertex == start )            cout<<weight[vertex]<<endl;        else            cout<<weight[vertex]<<" ";        return ;    }    cout<<weight[vertex]<<" ";}

但是有测试用例没有通过。

3、本题中我用到了递归,不但用到了,而且是递归中套递归。以前我总是避免使用递归,感觉比较难理解,但是程序本身也简洁了很多。比如树的先序,中序,后序遍历算法。

0 0