信号塔问题(看一次,爽一次,一直看,一直爽,嘻嘻)

说什么都不如先来个题目重要,是吧?
题目描述

有N个顶点,在顶点上放置信号塔则与之相邻的顶点能被信号覆盖到。
现在给你N-1条边,求解最少需要放置多少个信号塔才能使得所有顶点都有信号

输入

第一行:一个整数N
接下来N-1行:每行两个整数a和b(中间空格隔开,表示a和b相连)

输出

一个整数,最少需要放置信号塔的个数

样例输入

7
1 2
2 3
2 5
2 7
3 4
5 6

样例输出

3

(有信号 等价于 点亮)
首先,我们要明白,当前的状态取决于他所有孩子的状态

其实为了实现当前点以下所以点是亮的状态,我们需要的操作如下

主动亮—自己点亮的
被动亮—因为孩子亮了,所以才亮的
不亮–就是不会因为孩子而点亮

1,如果当前点的孩子中有一个不亮(状态为 0 ),那么当前点就一定要主动亮(状态为 1 )
2,如果当前点的孩子中有一个主动亮(状态为 1 ),那么当前点就一定是被动亮(状态为 -1 )
3,其他情况就是当前点的孩子都是被动亮(状态为 -1 ),那么当前点就一定不亮(状态为 0 )

废话不多说:“这代码,谁看谁知道,看一次,爽一次,一直看,一直爽”

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7;
vector<int> E[maxn];
int f[maxn]={0};    //储存当前节点的所有度
int v[maxn]={0};    //储存当前节点的状态( 0 -- 不亮   1 -- 主动亮   -1 --  被动亮)

int dfs(int k,int par)
{
    if(f[k]==1&&par!=0)return 0;
    
    int flg=0;
    for(int t : E[k]){
        if(t==par)      continue;       //如果是父亲,就跳过
        v[t]=dfs(t,k);                  //虽然就一句话,但是却是核心
        if(v[t]==0)  flg=1;             //第一种状态
        if(flg!=1&&v[t]==1) flg=-1;     //第二种状态
    }
    return flg;                         //第三种状态
}

int main()
{
    int n;cin >> n;
    for(int i=1,a,b;i<n;i++){
        cin >> a >> b;
        E[a].push_back(b);
        E[b].push_back(a);
        f[a]++;f[b]++;
    }

    v[1]=dfs(1,0);      //虽然就一句话,但是却是核心

    int ans=0;
    for(int i=1;i<=n;i++)   //遍历,找到需要安放信号塔的位置(v[i] == 1 )
        if(v[i]==1)ans++;

    
    if(v[1]==0)
        cout << ans+1 << endl;   //这里如果看不懂,估计上边你也不懂
    else
        cout << ans << endl;

    return 0;
}

在这里插入图片描述
日常搞事情,别管我,就当没看见

发布了15 篇原创文章 · 获赞 15 · 访问量 1170

猜你喜欢

转载自blog.csdn.net/weixin_44826485/article/details/90411002