P1038 神经网络
Posted garen-wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1038 神经网络相关的知识,希望对你有一定的参考价值。
复习图论系列。。。
这道题刚学OI的时候我就看过。被那个公式吓跑了。
其实那个公式也容易算嘛。
(C_i = sum_{(j,i) in E}{W_{ji} imes C_j} - u_i)
注意这个公式对输入层不适用!!!所以不管他的阈值。
我们用拓扑排序,从入度开始的来,用类似于刷表法的方法来更新所谓的(C_i)。
整个神经网络分为三个部分:输入层(入度为0),中间层(一般的点)和输出层(出度为0)。
最终只需要输出那些出度为0的就好了。中间层不要输出!!!
里面说的那个神经冲动,其实就是C值。两者是一样的。
注意:只有当前C值大于0才能传递冲动给后面。
然后就没有了。
我天真的写了个反图。。。结果没用到。
代码:
#include<cstdio>
#include<queue>
const int maxn = 105, maxm = 20005;
struct Edges
{
int next, to, weight;
} e[maxm], e2[maxm];
int head[maxn], tot, head2[maxn], tot2;
int indegree[maxn], outdegree[maxn];
int c[maxn], u[maxn];
int n, m;
void link(int u, int v, int w)
{
e[++tot] = (Edges){head[u], v, w};
head[u] = tot;
}
void link2(int u, int v, int w)
{
e2[++tot2] = (Edges){head2[u], v, w};
head2[u] = tot2;
}
void toposort()
{
std::queue<int> q;
for(int i = 1; i <= n; i++)
{
if(indegree[i] == 0 && c[i] > 0) q.push(i);
else c[i] = -u[i];
}
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i = head[u]; i; i = e[i].next)
{
int v = e[i].to;
if(c[u] > 0) c[v] += e[i].weight * c[u];
indegree[v]--;
if(indegree[v] == 0) q.push(v);
}
}
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d%d", &c[i], &u[i]);
while(m--)
{
int u, v, w; scanf("%d%d%d", &u, &v, &w);
link(u, v, w);
indegree[v]++; outdegree[u]++;
}
toposort();
bool flag = false;
for(int i = 1; i <= n; i++)
{
if(!outdegree[i] && c[i] > 0) printf("%d %d
", i, c[i]), flag = true;
}
if(!flag) printf("NULL
");
return 0;
}
以上是关于P1038 神经网络的主要内容,如果未能解决你的问题,请参考以下文章
VSCode自定义代码片段14——Vue的axios网络请求封装