拓扑排序模板题。
拓扑排序,是在一个$DAG$中,其拓扑排序为其所有结点的一个线性排序(答案不唯一)。
该排序满足这样的条件——对于图中的任意两个结点$u$和$v$,若存在一条有向边从$u$指向$v$,则在拓扑排序中$u$一定出现在$v$前面。
就好比一张流程图,必须完成这一步之前的所有步骤才能进行这一步。
代码实现:记录入度,每次走过一条边$(u,v)$将$v$的入度-1,入度为0时加入队列。
对于这道题,判断某个神经元是否兴奋(能继续传递)必须先走过到达这个神经元的每一条神经,恰好满足拓扑排序的定义。
注意:对于一个状态为负的神经元,需要将它的状态清零后加入队列(这样对后面不会有影响),否则如果不加入队列它后面点的入度没办法清零。
代码如下

#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #define MogeKo qwq using namespace std; #include<queue> const int maxn = 1005; queue <int> q; priority_queue < pair<int,int>,vector < pair<int,int> >,greater < pair<int,int> > > ans; int n,p,x,y,z,cnt; int c[maxn],u[maxn],in[maxn]; int to[maxn],head[maxn],nxt[maxn],val[maxn]; void add(int x,int y,int z){ to[++cnt] = y; nxt[cnt] = head[x]; head[x] = cnt; val[cnt] = z; } void topo(){ for(int i = 1;i <= n;i++) if(!in[i])q.push(i); while(!q.empty()){ int x = q.front(); q.pop(); if(!head[x]) if(c[x]>0) ans.push( make_pair(x,c[x])); for(int i = head[x];i;i = nxt[i]){ int y = to[i]; in[y]--; c[y] += c[x]*val[i]; if(!in[y]){ c[y] -= u[y]; if(c[y]<0) c[y] = 0; q.push(y); } } } } int main(){ scanf("%d%d",&n,&p); for(int i = 1;i <= n;i++) scanf("%d%d",&c[i],&u[i]); for(int i = 1;i <= p;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z); in[y]++; } topo(); if(ans.empty()){ printf("NULL"); return 0; } while(!ans.empty()){ printf("%d %d ",ans.top().first,ans.top().second); ans.pop(); } return 0; }