浏览器标题切换
浏览器标题切换end

寒假Day54:poj2378-Tree Cutting-没用树形dp写的树的题-dfs

题意:

给出一个n,代表一棵树有n个结点,接下去给出 n - 1 行,代表两个相连的结点

从小到大输出结点,结点满足的条件:当删去这个结点和与它相邻的边后,剩下的每一部分的节点都 ≤ n/2

 

思路:

用vector存邻边

从小到大输出结点 --->book标记最后再for循环遍历一遍即可

node数组存储的是该结点下所有的结点总和

 

看代码比较好理解

 

dfs部分代码:

int dfs(int x)
{
    bool flag=0;
    node[x]=1;
    for(int i=0; i<v[x].size(); i++)
    {
        int p=v[x][i];
        if(book1[p]==0)
        {
            book1[x]=1;//注意这边标记谁
            int w=dfs(p);//用一个变量代替,不要去调用两次dfs,因为状态有所改变
            if(w>n/2)
                flag=1;
            node[x]+=w;
        }
    }
    if(flag==0&&n-node[x]<=n/2)
        book2[x]=1;
    return node[x];
}

 

 

AC代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<vector>
using namespace std;

const int N=10020;

int n,node[N];
bool book1[N],book2[N];
vector<int>v[N];

int dfs(int x)
{
    bool flag=0;
    node[x]=1;
    for(int i=0; i<v[x].size(); i++)
    {
        int p=v[x][i];
        if(book1[p]==0)
        {
            book1[x]=1;//注意这边标记谁
            int w=dfs(p);//用一个变量代替,不要去调用两次dfs,因为状态有所改变
            if(w>n/2)
                flag=1;
            node[x]+=w;
        }
    }
    if(flag==0&&n-node[x]<=n/2)
        book2[x]=1;
    return node[x];
}

int main()
{
    while(cin>>n)
    {
        memset(book1,0,sizeof(book1));
        memset(book2,0,sizeof(book2));
        for(int i=1; i<n; i++)
        {
            int x,y;
            cin>>x>>y;
            v[x].push_back(y);
            v[y].push_back(x);
        }
        book1[1]=1;
        dfs(1);
        for(int i=1; i<=n; i++)
        {
            if(book2[i])
                cout<<i<<endl;
        }
    }
    return 0;
}

 

 

在网上看到这一片是用树形dp写的,下次学习,今天学不动了:

https://blog.csdn.net/sdau164185/article/details/78637106

posted @ 2020-03-17 22:30  抓水母的派大星  阅读(117)  评论(0编辑  收藏  举报