[NOIp2003提高组]神经网络

OJ题号:
洛谷1038

思路:
拓扑排序,注意细节。
1.题目中求和运算$C_i=\displaystyle{\sum_{(j,i)\in E}W_{ji}C_j-U_i}$中$U_i$在求和运算外,只要减一次。
2.输入层的神经元不需要减去$U_i$,可以事先将其赋值为$0$。
3.处于平静状态的神经元不会传导兴奋,但是拓扑排序时要将边去掉。

 #include<queue>
#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
char ch;
bool sgn=false;
while(!isdigit(ch=getchar())) if(ch=='-') sgn=true;
int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return sgn?-x:x;
}
const int V=;
struct Vertex {
int c,u;
};
Vertex v[V];
struct Edge {
int to,w;
};
std::vector<Edge> e[V];
inline void add_edge(const int u,const int v,const int w) {
e[u].push_back((Edge){v,w});
}
int in[V]={};
std::queue<int> q;
std::vector<int> ans;
inline void Kahn() {
while(!q.empty()) {
int x=q.front();
q.pop();
v[x].c-=v[x].u;
if(e[x].empty()&&v[x].c>) {
ans.push_back(x);
continue;
}
for(unsigned i=;i<e[x].size();i++) {
int &y=e[x][i].to;
if(v[x].c>) v[y].c+=e[x][i].w*v[x].c;
if(!--in[y]) {
q.push(y);
}
}
}
}
int main() {
int n=getint(),m=getint();
for(int i=;i<=n;i++) {
v[i].c=getint();
v[i].u=getint();
if(v[i].c) {
q.push(i);
v[i].u=;
}
}
while(m--) {
int u=getint(),v=getint(),w=getint();
add_edge(u,v,w);
in[v]++;
}
Kahn();
if(ans.empty()) {
puts("NULL");
}
else {
std::sort(ans.begin(),ans.end());
for(unsigned i=;i<ans.size();i++) {
printf("%d %d\n",ans[i],v[ans[i]].c);
}
}
return ;
}
上一篇:美国大学生数学建模竞赛绘图总结 - 使用Python matplotlib和pandas (以2021年美赛ICM D题为例)


下一篇:[学习笔记] CZT 变换