洛谷P1038 神经网络
1 //拓扑排序 坑点多 考验语文水平 2 #include<bits/stdc++.h> 3 #include<queue> 4 using namespace std; 5 const int maxn=105,maxm=10005; 6 queue<int> q; 7 struct edge{ 8 int to,dis;edge *Nex; 9 }e[maxm],*head[maxn]; 10 int top=-1; 11 void add(int x,int y,int z) 12 { 13 e[++top].to=y;e[top].dis=z; 14 e[top].Nex=head[x];head[x]=&e[top]; 15 } 16 int n,p,c[maxn],u[maxn],du[maxn]; 17 bool v[maxn]; 18 void topo() 19 { 20 for(int i=1;i<=n;++i) if(!du[i]) q.push(i),u[i]=0;//输入层的状态为读入默认状态 与公式无关(阈值按0算) 21 while(!q.empty()) 22 { 23 int p=q.front();q.pop(); 24 c[p]-=u[p]; 25 if(head[p]==NULL) v[p]=1;//打标记 只输出出度为0的点的状态 26 if(c[p]<=0) c[p]=0;//c<0 该神经元不会向下传输状态 但可以把c改成0 对后续计算无影响 方便统计出度为0的点 27 for(edge *i=head[p];i!=NULL;i=i->Nex) 28 { 29 --du[i->to]; 30 c[i->to]+=i->dis*c[p]; 31 if(!du[i->to]) q.push(i->to); 32 } 33 } 34 } 35 int main() 36 { 37 scanf("%d%d",&n,&p); 38 for(int i=1;i<=n;++i) scanf("%d%d",&c[i],&u[i]); 39 for(int i=1,x,y,z;i<=p;++i) scanf("%d%d%d",&x,&y,&z),add(x,y,z),++du[y]; 40 topo(); 41 bool flag=0; 42 for(int i=1;i<=n;++i) if(v[i]&&c[i]>0) printf("%d %d\n",i,c[i]),flag=1; 43 if(!flag) printf("NULL");//无输出需要输出NULL 44 return 0; 45 }