[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 }

 

posted @ 2017-08-19 15:27  skylee03  阅读(172)  评论(0编辑  收藏  举报