[2003提高组]神经网络-拓扑排序

Posted wyc06

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2003提高组]神经网络-拓扑排序相关的知识,希望对你有一定的参考价值。

题目
初始时Ci可以事先减去Ui,注意入度为0(即起始点)不要减。然后由于这张图是一个有向无环图,所以我们可以使用拓扑排序。排序完了过后就按照排好的顺序套给出的公式递推就行啦。
代码:

#include <iostream>
#include <queue>

using namespace std;
const int N=110,M=2*N*N;
int head[N],nxt[M],to[M],val[M],cnt;
int c[N],u[N],din[N],dout[N],a[N];
int n,m;

void add(int u,int v,int w) {
	to[++cnt]=v;
	val[cnt]=w;
	nxt[cnt]=head[u];
	head[u]=cnt;
}

void topo() {   //拓扑排序
	int tot=0;
	queue<int> q;
	for(int i=1;i<=n;i++)
	  if(!din[i])
	    q.push(i);
	while(!q.empty()) {
		int t=q.front();
		q.pop();
		a[++tot]=t;
		for(int i=head[t];i;i=nxt[i]) {
			int y=to[i];
			if(--din[y]==0)
			  q.push(y);
		}
	}
}

void work() {
	for(int i=1;i<=n;i++) {
		int x=a[i];
		if(c[x]>0)  //若活跃
		  for(int i=head[x];i;i=nxt[i]) {   //推向后继结点
			  int y=to[i];
			  c[y]+=val[i]*c[x];
		  }
	}
}

int main() {
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	  cin>>c[i]>>u[i];
	while(m--) {
		int u,v,w;
		cin>>u>>v>>w;
		add(u,v,w);
        //增加出入度
		din[v]++;
		dout[u]++;
	}
	for(int i=1;i<=n;i++)
	  if(din[i])
	    c[i]-=u[i]; //事先减去阈值
	topo();
	work();
	bool flag=false;
	for(int i=1;i<=n;i++)
	  if(dout[i]==0 and c[i]>0)
	    cout<<i<<‘ ‘<<c[i]<<endl,flag=true; //出度为0且C>0的输出
	if(!flag)   //特判
	  cout<<"NULL";
	return 0;
}


以上是关于[2003提高组]神经网络-拓扑排序的主要内容,如果未能解决你的问题,请参考以下文章

noip2003提高组题解

水王争霸(2003noip提高组)

topsort | | jzoj[1226] | | NOIP2003神经网络

图--03---有向图拓扑排序

noip提高组复赛所需掌握的东西

拓扑排序之变量序列代码