P1038 神经网络 的题解。
code
先 po 一下 :
#include<bits/stdc++.h>
#define _ 0
using namespace std;
struct edge
{
int nxt,end,len;
}e[100*100+5];
int n,p,head[100+5],cnt=0,outf=1;
int c[100+5],u[100+5],type[100+5],v[100+5][100+5];
queue<int>q;
inline void add(int x,int y,int l)//喜闻乐见的链式前向星
{
e[++cnt]=(edge){head[x],y,l};
head[x]=cnt;
return;
}
void bfs()
{
for(int i=1;i<=n;i++)
if(type[i]==1)
q.push(i);
while(!q.empty())
{
bool flag=1;
int now=q.front();
q.pop();
if(!v[now][0])//v[i][0]==1表示这个神经元的C已运算完
{
if(type[now]!=1)
c[now]-=u[now];//公式的后半部分,减去阈值
v[now][0]=1;
}
for(int i=head[now];i;i=e[i].nxt)
{
int next=e[i].end;
if(!v[next][0]&&!v[next][now]&&c[now]>0)
c[next]+=e[i].len*c[now],v[next][now]=1;//v[i][...]打标记去重
flag=0,q.push(next);
}
if(flag)
type[now]=2;
}
return;
}
int main()
{
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&c[i],&u[i]);
if(c[i]!=0)
type[i]=1;
}
for(int i=1;i<=p;i++)
{
int t1,t2,t3;
scanf("%d%d%d",&t1,&t2,&t3);//建图
add(t1,t2,t3);
}
bfs();
for(int i=1;i<=n;i++)
if(type[i]==2&&c[i]>0)
outf=0,printf("%d %d\n",i,c[i]);
if(outf)//是否输出NULL
printf("NULL");
return ~~(0^_^0);//嘤嘤嘤 放心不会CE
}
思路
很清晰!依照题意膜你,输出即可!
主要思路
每层神经元只向下一层的神经元输出信息,只从上一层神经元接受信息。
所以,这是个 DAG。
非输入层的神经元开始时状态必然为 。
所以,读入时,先将最初状态为 的神经元的 type[]
设为 ,表示输入层。
因为数据范围较小(),直接在 bfs 中暴枚,找到 type[i]==1
的神经元。
将这些神经元压入队列。
在 bfs 中,算出各神经元的状态值:
- 在拓展 号神经元时,先算出 。(line 36)
- 若要用此 号神经元拓展其他点时,表明 运算已结束,减去阈值 (line 29)。
在bfs,如果 flag
(line 23)为真,表明这个神经元出度为 ,即为输出层(line 40)。
因为数据范围较小(),直接在数组中暴枚,找到 type[i]==2&&c[i]>0
的神经元,并输出。
难点在于,题目坑太多了!~~我太弱了,不知道大佬们用的拓扑排序,~~所以有什么不严谨的地方敬请指出。
坑 #1
我只是初中蒟蒻,公式看不懂啊!!!
经过自学后,了解了, 表示求和。 等价于:
for(int i=1;i<=n;i++)
sum+=a[i];//sum的结果
而 表示 这个元素包含在集合 中。
所以 就表示以下伪代码中 sum
的结果。
//对于i点
for(int tmp=head[i];tmp;tmp=e[i].nxt)//链式前向星,所有与i相连的神经元
{
int j=e[i].end;
sum+=e[tmp].len*c[j];
}
sum-=u[i];
//其中i,j,c[],u[]的意义与公式对应;e[tmp].len即w[j][i]
注意:
是减在后面!
当 大于 时,该神经元处于兴奋状态,否则就处于平静状态。当神经元处于兴奋状态时,下一秒它会向其他神经元传送信号。所以在 时,该神经元才会对 有贡献!
该公式对输入层不适用!
坑 #2
若输出层的神经元最后状态均为 ,则输出
NULL
。
题面有误:不是均为 !是均小于等于 !
仅输出最后状态大于的输出层神经元状态,并且按照编号由小到大顺序输出。
已加粗。
坑 #3
当神经元处于兴奋状态时,下一秒它会向其他神经元传送信号,信号的强度为 。
其实“传送信号”就是参与公式运算!
坑 #4
, 都有可能为负数或 !
本文作者:Yurchiu
本文链接:https://yz-hs.github.io/9492bebde047/
版权声明:本博客中所有原创文章除特别声明外,均允许规范转载,转载请注明出处。所有非原创文章,按照原作者要求转载。