1038神经网络

1038神经网络

这道题也可以用队列来做,但比较麻烦。。。。没办法,蒟蒻一枚。

首先,将起点(ci==1的点)放入队列之中。当head< tail时,

++head,将队首的点(team【head】)展开去找他的儿子节点。

如果儿子节点没放入队列则放入。l代表本层最后一个点在team【】中的序号,l2用于记录修改前的l,便于输出。当head==l时,则这一层的节点扫描毕。此时l+1到tail间的节点即是下一层的节点。对下一层的节点施行减ui【】操作,如果减完后的ci【】大于0,则这个节点处于兴奋状态,可以向下传递。若不能,则用ex【】(因为exst【】已经用来记录别的了。。。)打个标记阻止继续下传。循环完成后,l2+1到l(也就是tail)之间的便是解(注意只用输出大于0的,所以输出时加一个判定),至于co【】,只是为了按顺序输出用的。

解释写得够详细得了吧。。。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
using namespace std;
int n,p,ta,ci[1000001],ui[1000001];
int head,l2,tail,team[1000001],exist[100010];
int ex[1000001],co[1000001],lx;
struct ac
{
    int t,s,next,head,w;
}e[100001*4];
void build(int x,int y,int z)
{
    e[++ta].t=y;
    e[ta].w=z;
    e[ta].s=x;
    e[ta].next=e[x].head;
    e[x].head=ta;

}//建图。

bool cmp(int a,int b)
{
    return a<b;
}
int main()
{
    cin>>n>>p;
    for(int i=1;i<=n;++i)
    {
        cin>>ci[i]>>ui[i];
    }
    for(int i=1;i<=p;++i)
    {
        int a,b,c;
        cin>>a>>b>>c;
        build(a,b,c);
    }
    for(int i=1;i<=n;++i)
    {
        if(ci[i]!=0)
        {
            team[++tail]=i;
        }

}//起点入队。 int l=tail;//此时l为第一层最后一个节点在team【】中的序号。

    while(head<tail)
    {
        if(head==l)//当某一层循环完毕时,执行减ui【】操作。
        {
            for(int i=l+1;i<=tail;++i)
            {
                ci[team[i]]=ci[team[i]]-ui[team[i]];
                if(ci[team[i]]<=0)//如果细胞不兴奋则标记。
                {
                    ex[team[i]]=1;
                }
            }
            l2=l;
            l=tail;//更新l,l2.
        }
        head++; int u=team[head];
       if(ex[u]!=1)//如果节点兴奋,则修改他的子节点。
        {
            for(int i=e[u].head;i;i=e[i].next)
            {
                int go=e[i].t;
                ci[go]+=ci[e[i].s]*e[i].w;
                if(exist[go]!=1)
                {    //如果子节点未入队则入队。
                    exist[go]=1;
                    team[++tail]=go;
                }
            }
        }
    }
    for(int i=l2+1;i<=tail;++i)
    {
        co[++lx]=team[i];
    }
    sort(co+1,co+1+lx,cmp);//从下到大输出。
    if((ci[co[lx]]==0&&ci[co[1]]==0)||tail<n)
    {
        cout<<"NULL";//如果首尾都是0(因为sort过了,所以如果首尾都是0则全是0)或未遍历到输出层,则输出NULL。
    }
    else
    {
        for(int i=1;i<=lx;++i)
        {
            if(ci[co[i]]>0)
            cout<<co[i]<<" "<<ci[co[i]]<<'\n';
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值