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 神经网络的主要内容,如果未能解决你的问题,请参考以下文章

P1038 神经网络

p1038 神经网络

P1038 神经网络

VSCode自定义代码片段14——Vue的axios网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装