题解 P1038 【神经网络】

shadowice1984

2017-09-30 17:28:03

题解

这里着重讲一下审题。

第三,第五个点卡了很久。。。

一直不知怎么回事。

后来发现题目里有一句话叫“在输入层神经元被激发之后”

所以题目中的ui并不是完全无用的!

题目的意思是,第一层神经元的ci是钦定的,不由公式计算;

并且在开始时手动激活所有输入神经元!

但是为了这个开个数组似乎不值~

所以我们在输入是加一个判断,如果ci!=0,则ui=0;

然后拓扑排个序,裸做就行了。

上代码~

#include<stdio.h>
#include<queue>
using namespace std;
int n;int p;
queue <int> q;int now;
int c[10000];
int map[10000][10000];//邻接矩阵存图
bool wap[10000][10000];bool book[10000];
int tp[10000];int cnt=0;
int res[10000];int cot=0;
const int inf=9999999;
int main()
{
    scanf("%d%d",&n,&p);
    for(int i=0;i<n;i++)//手动memset
    {
        for(int j=0;j<n;j++)
        {
            map[i][j]=inf;
        }
    }
    for(int i=0;i<n;i++)
    {
        int set;int u;
        scanf("%d%d",&set,&u);
        if(set!=0)u=0;//灵魂特判,40分的区别
        c[i]=set-u;
    }
    for(int i=0;i<p;i++)
    {
        int u;int v;int val;
        scanf("%d%d%d",&u,&v,&val);
        map[u-1][v-1]=val;wap[u-1][v-1]=true;//从零开始的数组
    }
    for(int i=0;i<n;i++)//tuopu排序
    {
        q.push(i);
    }   
    while(!q.empty())
    {
        now=q.front();
        for(int i=0;i<n;i++)
        {
            if(wap[i][now])goto skip;//goto语句实现检测入边
        }
        q.pop();
        for(int i=0;i<n;i++)
        {
            wap[now][i]=false;
        }
        tp[cnt++]=now;continue;
        skip:;
        q.push(now);q.pop();
    }
    for(int i=0;i<n;i++)
    {
        if(c[tp[i]]<=0)continue;
        for(int j=0;j<n;j++)
        {
            if(map[tp[i]][j]==inf)continue;
            c[j]+=c[tp[i]]*map[tp[i]][j];    //处理权值    
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(map[i][j]!=inf)goto skipii;//找出度为0的点
        }
        res[cot++]=i;
        skipii:;
    }
    bool flag=true;
    for(int i=0;i<cot;i++)//输出
    {
        if(c[res[i]]<=0)continue;flag=false;
        printf("%d %d\n",res[i]+1,c[res[i]]);
    }
    if(flag)
    {
        printf("NULL");
    }
    return 0;//拜拜程序~
}