[刷题之旅no31]P1038 [NOIP2003 提高组] 神经网络

仔细一看,仔细一想,唔
是bfs。
1.数据结构:
1.链式前向星
2.line队列
3.u数组记录结点阈值
4.c数组记录结点兴奋程度
5.out数组用于记录最终输出结果
6.队列设置三个拨针,head,tail和lasttail(lasttail用于记录上一层级结点的最后一位的下标)
7.isinline数组,判断当前元素是否入队
8.flag判断到底能不能兴奋
思路:
1.读取点的数量和边的数量
2.读取点,按顺序记录点的刺激点c和阈值u,更新c和u数组值,将刺激点c大于0的点入列,同时更新tail和taillast值,还有数组isinline的值
3.读取边,用链式前向星读取
4.while循环(队列不为空)
5.取出队首元素
(处理队首元素)
{
6.判断他的刺激值是否等于0
6.1等于0,那么他对后面的神经元不起作用continue
6.2不等于0,
6.2.1判断当前结点是否指向了其他节点,也就是先判断linkfedge[node]==0
等于0,并且c[node]>0,直接out数组值更新,flag=1;
6.2.2不等于0,说明其本身存在结点
则遍历他指向的所有神经节点,然后更新数组c的值,并把没有入队的结点入队,更新isinline
}
7.head++;
先判断是否空队列,head>tail
如果大于直接break
否则
判断当前的head是否大于taillast
7.1如果不大于,continue
7.2大于,说明上一次层级已经全部计算完成
while(1)循环
taillast++;
更新对应下标指向元素的数组c的值减去阈值
判断是否大于0,大于0保留,否则等于0
判断taillast是否等于tail,如果等于,break掉
8.flag=1;按照顺序,判断out中的值,不为0则输出
flag=0;输出NULL;
结束
完美的铲球!芜湖!

#include<stdio.h>
int line[105]={0},u[105]={0},c[105]={0},out[105]={0},isinline[105]={0},linkfedge[105]={0};
int head=1,tail=0,taillast=0,flag=0,n,p,st,en,dis,cnt=0,node;
typedef struct
{
	int tonode,nextEdge,dis;
}Edge;
Edge edge[5000];
void scan()
{
	scanf("%d %d",&n,&p);
	for(int i=1;i<=n;i++)
	{
		scanf("%d %d",&c[i],&u[i]);
		if(c[i]>0)
		{
			tail++;
			line[tail]=i;
			isinline[i]=1;
		}
	}
	taillast=tail;
}
void createdge(int from,int to,int dis)
{
	cnt++;
	edge[cnt].nextEdge=linkfedge[from];
	edge[cnt].tonode=to;
	edge[cnt].dis=dis;
	linkfedge[from]=cnt;
}
void creat()
{
	scan();
	for(int i=1;i<=p;i++)
	{
		scanf("%d %d %d",&st,&en,&dis);
		createdge(st,en,dis);
	}
}
void bfs()
{
	int tmpnode;
	while(1)
	{
		node=line[head];
		if(c[node]!=0)//取出队首元素进行遍历处理 
		{
			if(linkfedge[node]==0&&c[node]>0)
			{
				out[node]=c[node];
				flag=1;
			}
			else
			{
				for(int noedge=linkfedge[node];noedge;noedge=edge[noedge].nextEdge)
				{
					tmpnode=edge[noedge].tonode;
					c[tmpnode]=c[tmpnode]+edge[noedge].dis*c[node];
					if(isinline[tmpnode]==0)
					{
						tail++;
						line[tail]=tmpnode;
						isinline[tmpnode]=1;
					}
				}
			}
		}
		head++;//队首元素出列
		if(head>tail)
		{
			break;
		}
		if(head>taillast)
		{
			while(1)
			{
				taillast++;
				tmpnode=line[taillast];
				c[tmpnode]=c[tmpnode]-u[tmpnode];
				if(c[tmpnode]<0)
				{
					c[tmpnode]=0;
				}
				if(taillast==tail)
				{
					break;
				}
			}
		}
	}
}
void print()
{
	if(flag)
	{
		for(int i=1;i<=n;i++)
		{
			if(out[i]!=0)
			{
				printf("%d %d\n",i,out[i]);
			}
		}
	}
	else
	{
		printf("NULL\n");
	}
}
int main()
{
	creat();
	bfs();
	print();
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值