P1038 [NOIP2003 提高组] 神经网络

题意:给你一个有向无环图,并且给定每一个结点的初始状态和阈值(非输入层的结点的初始状态必为0),求输出层的所有结点的状态,只输出状态值大于0的

思路:拓扑排序一遍得到拓扑序,然后根据拓扑序用前面的结点算它的所有后继结点的状态值,最后遍历所有结点,输出位于输出层(出度=0)并且状态值>0的点

注意:神经网络中的一个结点i,只有状态\(C_i>0\)时,它才会参与到后继结点状态值的计算

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>

using namespace std;

#define PII pair<int, int>

const int N = 110, INF = 0x3f3f3f3f;

int in[N], out[N], st[N];
int g[N][N];
int u[N], c[N];

int n, p;

vector<PII> topsort(){
    queue<int> q;
    for(int i = 1; i <= n; i ++)
        if(in[i] == 0){
            q.push(i);
            st[i] = 1;
        }
    
    vector<PII> ans;
    while(q.size()){
        int h = q.front();
        q.pop();
        if(!st[h]) c[h] -= u[h];
        if(out[h] == 0){
            if(c[h] > 0)
                ans.push_back({h, c[h]});
            continue;
        }
        for(int i = 1; i <= n; i ++)
            if(g[h][i] != INF){
                if(c[h] > 0) c[i] += g[h][i] * c[h];
                in[i] --;
                if(in[i] == 0) q.push(i);
            }
    }       
    
    return ans;
}

int main(){
    memset(g, 0x3f, sizeof g);
    cin >> n >> p;
    
    for(int i = 1; i <= n; i ++) cin >> c[i] >> u[i];
    
    while(p --){
        int a, b, w;
        cin >> a >> b >> w;
        
        g[a][b] = w;
        in[b] ++;
        out[a] ++;
    }
    
    vector<PII> res = topsort();
    
    sort(res.begin(), res.end());
    
    if(res.size())
        for(int i = 0; i < res.size(); i ++) 
            cout << res[i].first << ' ' << res[i].second << endl;
    else puts("NULL");
    
    return 0;
}
posted @ 2021-07-03 10:43  yys_c  阅读(160)  评论(0编辑  收藏  举报