https://www.luogu.org/problem/P1038
题目背景
人工神经网络(Artificial Neural NetworkArtificialNeuralNetwork)是一种新兴的具有自我学习能力的计算系统,在模式识别、函数逼近及贷款风险评估等诸多领域有广泛的应用。对神经网络的研究一直是当今的热门方向,兰兰同学在自学了一本神经网络的入门书籍后,提出了一个简化模型,他希望你能帮助他用程序检验这个神经网络模型的实用性。

题目描述
在兰兰的模型中,神经网络就是一张有向图,图中的节点称为神经元,而且两个神经元之间至多有一条边相连,下图是一个神经元的例子:
在这里插入图片描述
在这里插入图片描述
输入输出样例
输入 #1 复制

5 6
1 0
1 0
0 1
0 1
0 1
1 3 1
1 4 1
1 5 1
2 3 1
2 4 1
2 5 1

输出 #1 复制

3 1
4 1
5 1

根据题意:
输入层—>中间层---->输出层
我们可以发现只要有出度的都不属于输出层。
也很明显是一个拓扑排序。
本题只有三层,我分别给前两层标号1,2,
对于非输入层的点根据题目中的公式要减掉U,
在输入的时候我们就可以根据题意判断出非输入层的点,
然后让它的c先减掉u,这样我们后面计算C,只需要管求和部分

#include <bits/stdc++.h>
using namespace std;
struct Node
{
    int c,u;
    int no;
    int in,index;
    Node()
    {
        in = 0;
        index = 0;
    }
    Node(int id,int i):index(id),in(i)
    {
    }
    bool operator<(const Node&x)const
    {
        return in > x.in;
    }
} a[105];
struct Edge
{
    int to;
    int val;
    Edge(int t,int v):to(t),val(v)
    {
    }
};
vector<Edge>vec[105];
int main()
{
    int n,p;
    scanf("%d%d",&n,&p);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d%d",&a[i].c,&a[i].u);
        a[i].c ? a[i].no = 1 : a[i].c -= a[i].u;
    }
    while(p--)
    {
        int x,y,v;
        scanf("%d%d%d",&x,&y,&v);
        if(a[x].no != 1) a[x].no = 2;
        vec[x].push_back(Edge(y,v));
        a[y].in++;
    }
    priority_queue<Node>q;
    for(int i = 1; i <= n; i++)
    {
        if(a[i].no == 1)
        {
            q.push(Node(i,0));
        }
    }
    while(!q.empty())
    {
        while(!q.empty())
        {
            Node k = q.top();
            q.pop();
            int cnt = vec[k.index].size();
            for(int i = 0; i < cnt; i++)
            {
                int t = vec[k.index][i].to;
                int v = vec[k.index][i].val;
                if(a[k.index].c > 0)//题意,只需加大于0的部分
                    a[t].c += a[k.index].c * v;
                a[t].in--;
            }
            //需要特判:对于一个没有出度的输入层的点,它自身也是属于输出层
            if(cnt) a[k.index].in = -1;//有出度的去掉这个点,置为-1来标记
        }
        for(int i = 1; i <= n; i++)
        {
            if(a[i].no == 2 && a[i].in == 0)//此时入度为0的第二层(中间层)入队列
            {
                q.push(Node(i,a[i].in));
            }
        }
    }
    int flag = 0;
    for(int i = 1; i <= n; i++)
    {
        if(a[i].in != -1&&a[i].c > 0)//根据题意打印
        {
            flag = 1;
            printf("%d %d\n",i,a[i].c);
        }
    }
    if(!flag) printf("NULL\n");
    return 0;
}


/*
4 4
1 0
0 1
0 1
0 1
1 2 1
1 3 1
2 3 1
3 4 1


5 8
1 0
1 0
0 1
0 1
0 1
1 3 1
1 4 1
1 5 1
2 3 1
2 4 1
2 5 1
3 5 1
5 4 1

1 0
1 1
*/
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐