P1038 神经网络 题解
神经网络
题意
有
每个节点可以长成这样:
每个节点都有一个内在参数
节点按照一定顺序排列,可分为三种类型:输入层,中间层和输出层,每个节点只可从上一层接受信息,向下一层传递信息。
对于每个点的状态,有以下公式:
其中
当
给定了每个节点的初始状态和内在参数,
不是输入层的节点初始状态一定为
请求出所有 NULL
数据范围
- 两个节点直接最多只有一条边
思路
很明显,这里不会有环和重边,拓扑序也可以轻松发现。
那么这题就是拓扑排序的天下了,在求拓扑序的同时去求一下
细节
1 公式
只有
也就是说,公式可以变成这样:
2 逻辑
题意中有一个逻辑坑点:
不是输入层的节点初始状态一定为
并没有说输入层的节点初始状态一定不为
3 分类
输入层的节点不参与公式计算,即不会减去内在参数。
复杂度
- 时间:
- 空间:
Code
点击查看代码
#include <iostream> #include <vector> #include <queue> using namespace std; struct node { int f, u; } a[110]; struct Node { int x, y; }; int n, m, ansf, x, y, z, b[110], c[110]; vector<Node> v[110]; void dfs (int x) { b[x]--; // 相当于一种标记 if (!a[x].f) { // 不是输入层 c[x] -= a[x].u; // 减去内在参数 } for (auto i : v[x]) { b[i.x]--; if (c[x] > 0) { // 只有当前点的ci>0时才可以发送信号 c[i.x] += c[x] * i.y; // 公式套上 } if (!b[i.x]) { // 这个点计算完了 dfs(i.x); // 调用一下 } } } int main(){ ios::sync_with_stdio(0), cin.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> a[i].f >> a[i].u; // 初始状态和内在参数 } for (int i = 1; i <= m; i++) { cin >> x >> y >> z; v[x].push_back({y, z}); // 边 b[y]++; } for (int i = 1; i <= n; i++) { if (a[i].f) { // 输入层 c[i] = a[i].f; dfs(i); } } for (int i = 1; i <= n; i++) { if (!v[i].size() && c[i] > 0) { // 输出层且满足要求 cout << i << ' ' << c[i] << '\n'; // 输出一下 ansf = 1; // 标记有答案 } } if (!ansf) { // 没有答案,输出NULL cout << "NULL"; } return 0; }
本文作者:wnsyou の blog
本文链接:https://www.cnblogs.com/wnsyou-blog/p/17214119.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步