P1269 信号放大器

P1269 信号放大器

题意:给出一个树形结构,1号为根节点,每个节点都能接收和发射信号。每条边有一个消耗,若到达某个节点时信号值为负,则可以在它的父节点处放置一个信号放大器,使它的父节点发出的信号值等于根节点发出的信号值。
问如果可以使所有节点都接收到信号,需要的最少的信号放大器。否则输出""

思路:先 F a Fa Fa数组存下各个子节点到 n o w now now节点的距离,再遍历到根节点,再往上找以 n o w now now节点为子树的深度,用 d i s dis dis数组存起来,。返回到 n o w now now节点时,如果 d i s [ n o w ] + F a [ n o w ] > m dis[now]+Fa[now]>m dis[now]+Fa[now]>m,表示在 n o w now now节点的父节点 f a fa fa节点发出的信号不能完全覆盖 n o w now now子树,说明在 f a fa fa节点必须放一个信号放大器。 d i s [ n o w ] dis[now] dis[now]就应该改成 0 0 0

#include<bits/stdc++.h>
using namespace std;
const int N = 20010;
const int inf = 0x7ffffff;
int head[N], tot = 1, ans = 0;
int dis[N], Fa[N];
struct tree{
    
    
    int to, next, v;
} t[N<<1];

void add(int x, int y, int we) {
    
    //图的存储
    t[tot].to = y , t[tot].next = head[x], t[tot].v = we, head[x] = tot++;
}

void dfs(int now, int fa, int m) {
    
    //dfs遍历
    for(int i=head[now]; i != 0; i=t[i].next) {
    
    
        if(t[i].to != fa) {
    
    
            Fa[t[i].to] = t[i].v;//记录节点到其父亲的深度
            dfs(t[i].to, now, m);//往下遍历
            dis[now] = max(dis[t[i].to]+t[i].v, dis[now]);//找子树深度
        }
    }
    if(Fa[now] + dis[now] > m) ans++, dis[now] = 0;//判断是否要放信号放大器。
}
int main() {
    
    
    int n, m, x, y, f = 0;
    cin >> n;
    for(int i=1; i<=n; i++) {
    
    
        cin >> m;
        for(int j=0; j<m; j++) {
    
    
            cin >> x >> y;
            f = max(f, y);
            add(i, x, y);
        }
    }
    cin >> m;
    if(f >= m) {
    
    cout << "No solution."; return 0;}//特判,不能完全覆盖的情况
    dfs(1, 0, m);
    cout << ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45363113/article/details/108569100