洛谷习题

2019-05-21 P1038 神经网络

2019-05-21  本文已影响0人  桐桑入梦

题目链接:https://www.luogu.org/problemnew/show/P1038

使用拓扑排序的思想处理的神经网络:
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=101;
typedef vector<int> vec;
struct Node{
    int v,w;
    Node(int v=0,int w=0):v(v),w(w){}
}; 
vector<Node>G[maxn];
int n,p,U[maxn],C[maxn],in[maxn],out[maxn];

vec solve(){
    vec ans;
    queue<int>que;
    for(int i=1;i<=n;i++){
        if(in[i]==0) {
            U[i]=0;//第一层神经元不需要减去阈值,所以处理为0 
            que.push(i);
        }
    }
    while(!que.empty()){
        int u=que.front(); que.pop();
        C[u]-=U[u];//减去阈值
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i].v;
            int w=G[u][i].w;
            in[v]--;
            if(in[v]==0) que.push(v);//如果入度为0,那么可以加入队列中 
            if(C[u]>0) C[v]+=w*C[u];//如果处于兴奋状态,对下一层的神经元传递信号 
        } 
    }
    for(int i=1;i<=n;i++){
        if(out[i]==0 && C[i]>0){
            ans.push_back(i);
        }
    }
    return ans; 
}
int main(void){
    cin>>n>>p;
    for(int i=1;i<=n;i++) cin>>C[i]>>U[i];
    for(int i=1;i<=p;i++){
        int u,v,w;
        cin>>u>>v>>w;
        in[v]++;
        out[u]++;
        G[u].push_back(Node(v,w));      
    }
    vec ans=solve();
    if(ans.size()==0) cout<<"NULL";
    else{
        for(int i=0;i<ans.size();i++){
            int u=ans[i];
            cout<<u<<" "<<C[u]<<endl; 
        }
    }
    return 0;
}
没有什么固定的思路,就是使用了点bfs和拓扑排序的思路:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;

const int maxn=101;
struct Node{
    int v,w;
    Node(int v=0,int w=0):v(v),w(w){} 
};
vector<Node> Adj[maxn];
int n,p,U[maxn],C[maxn],level[maxn],in[maxn],out[maxn],used[maxn];

vector<int> solve(){
    queue<int>que;
    for(int i=1;i<=n;i++){
        if(in[i]==0 && C[i]>0){//如果是输入层并且处于兴奋状态 
            que.push(i);//加入队列 
            used[i]=true;//记录是否加入队列 
        }
    }
    while(!que.empty()){//使用bfs的思想进行一层一层的处理 
        int u=que.front(); que.pop();
        //当一个非输入层的神经元出队列的时候,减去阈值
        if(in[u]!=0) C[u]-=U[u];//此时已经计算出了状态 
        if(C[u]<=0) continue;//如果这个神经元处于平静状态,不需要往下处理了 
        for(int i=0;i<Adj[u].size();i++){//这个神经元向下层传递信号 
            int v=Adj[u][i].v;
            int w=Adj[u][i].w;
            //如果当前的神经元兴奋 
            //对下一层输出信号 
            C[v]+=w*C[u]; 
            if(!used[v]){
                used[v]=true;
                que.push(v);
            }
        }
    }

    vector<int>vec;
    for(int i=1;i<=n;i++)
        if(out[i]==0 && C[i]>0)//如果是输出层
            vec.push_back(i);
    return vec;
}
int main(void){
    cin>>n>>p;
    for(int i=1;i<=n;i++) cin>>C[i]>>U[i];
    int u,v,w;
    for(int i=1;i<=p;i++){
        cin>>u>>v>>w;
        Adj[u].push_back(Node(v,w));
        in[v]++;//记录有输入边的顶点,没有输入边的顶点是输出层 
        out[u]++;
    }
    vector<int> vec = solve();
    
    bool isnull; 
    if(vec.size()==0) isnull=true;
    else isnull=false;
    
    if(isnull) cout<<"NULL"<<endl;
    else{
        for(int i=0;i<vec.size();i++){
            int u=vec[i];
            cout<<u<<" "<<C[u]<<endl;
        } 
    } 
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读