题解—— 洛谷 p1269 信号放大器(贪心)

 

深刻的教训,不要写错读入

#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 150001;
const int MAXM = 250001;
int cnt=0,u[MAXM],v[MAXM],w[MAXM],first[MAXN],next[MAXM];
int dis[MAXN],st,ans=0,n,fa[MAXN];
inline int qread(void){
    int x=0;
    char s;
    s=getchar();
    while(s>'9'||s<'0')
        s=getchar();
    while(s>='0'&&s<='9'){
        x*=10;
        x+=s-'0';
        s=getchar();
    }
    return x; 
}
inline void qwrite(int x){
    if(x>9){
    qwrite(x/10);
    }
    putchar(x%10+'0');
}
void addedge(int ux,int vx,int wx){
    ++cnt;
    u[cnt]=ux;
    v[cnt]=vx;
    w[cnt]=wx;
    next[cnt]=first[ux];
    first[ux]=cnt;
}
void dfs2(int x,int f){
    for(int i=first[x];i;i=next[i]){
        if(v[i]==f)
            continue;
        fa[v[i]]=w[i];
        dfs2(v[i],x);
        dis[x]=max(dis[v[i]]+w[i],dis[x]);
    }
    if(dis[x]+fa[x]>st){
        ans++;
        dis[x]=0;
        }
}
int main(){
    n=qread();
    int m=0;
    for(int i=1;i<=n;i++){
        int mid;
        mid=qread();
        for(int j=1;j<=mid;j++){
            int vx,wx;
            vx=qread();
            wx=qread();
            addedge(i,vx,wx);
            m=max(m,wx);
        }
    }
    st=qread();
    if(m>=st){
        printf("No solution.\n");
        return 0;
    }
    dfs2(1,1);
    qwrite(ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/dreagonm/p/9420046.html

C++信号放大器 (1) 运用二叉树的定义将左孩子、右孩子、结点值、权值即与父结点的衰减量、以及当前结点的最大衰减量联系起来。 (2) 设置信号放大器函数 该函数主要实现判断是否超过容忍值并在合适位置放置信号放大器使其数量最少。 首先将当前结点最大衰减量D初始化,当只有右子树时即左子树为空,计算出当前结点的最大衰减量,判断当超过容忍值时则放置信号放大器并输出;当只有左子树时即右子树为空,计算出当前结点的最大衰减量,判断当超过容忍值时则放置信号放大器并输出;当左右子树都存在并左子树的衰减量大于右子树时则计算当前结点最大衰减量D并判断是否超过容忍值并输出,继续进一步比较其右子树的当前最大衰减量与右子树的衰减量之和和其左子树的衰减量,若大于则更新D,并判断是否超过容忍值并输出,再进一步比较其右子树的衰减量与其左子树的衰减量,若大于则再更新D;当左右子树都存在且右子树的衰减量大于左子树时,比较方法与前者相似,颠倒左右即可。 通过此算法可将放置的放大器数目最少。 (3) 主函数 主函数中包括输入信息时的声明及相关函数的调用。 四 调试分析 该程序在设置信号放大器的比较算法上有些麻烦,需要进行很多比较。结点信息的输入也比较麻烦,很浪费时间,还有就是输出结果时最好将二叉树的具体结构一同输出便于检查,并且形象直观。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值