[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.处于平静状态的神经元不会传导兴奋,但是拓扑排序时要将边去掉。
1 #include<queue> 2 #include<cstdio> 3 #include<cctype> 4 #include<algorithm> 5 inline int getint() { 6 char ch; 7 bool sgn=false; 8 while(!isdigit(ch=getchar())) if(ch=='-') sgn=true; 9 int x=ch^'0'; 10 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 11 return sgn?-x:x; 12 } 13 const int V=101; 14 struct Vertex { 15 int c,u; 16 }; 17 Vertex v[V]; 18 struct Edge { 19 int to,w; 20 }; 21 std::vector<Edge> e[V]; 22 inline void add_edge(const int u,const int v,const int w) { 23 e[u].push_back((Edge){v,w}); 24 } 25 int in[V]={0}; 26 std::queue<int> q; 27 std::vector<int> ans; 28 inline void Kahn() { 29 while(!q.empty()) { 30 int x=q.front(); 31 q.pop(); 32 v[x].c-=v[x].u; 33 if(e[x].empty()&&v[x].c>0) { 34 ans.push_back(x); 35 continue; 36 } 37 for(unsigned i=0;i<e[x].size();i++) { 38 int &y=e[x][i].to; 39 if(v[x].c>0) v[y].c+=e[x][i].w*v[x].c; 40 if(!--in[y]) { 41 q.push(y); 42 } 43 } 44 } 45 } 46 int main() { 47 int n=getint(),m=getint(); 48 for(int i=1;i<=n;i++) { 49 v[i].c=getint(); 50 v[i].u=getint(); 51 if(v[i].c) { 52 q.push(i); 53 v[i].u=0; 54 } 55 } 56 while(m--) { 57 int u=getint(),v=getint(),w=getint(); 58 add_edge(u,v,w); 59 in[v]++; 60 } 61 Kahn(); 62 if(ans.empty()) { 63 puts("NULL"); 64 } 65 else { 66 std::sort(ans.begin(),ans.end()); 67 for(unsigned i=0;i<ans.size();i++) { 68 printf("%d %d\n",ans[i],v[ans[i]].c); 69 } 70 } 71 return 0; 72 }