拓扑排序:
不断取出入度为0的点,拓扑排序因此不唯一
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<cstdio>
#include<algorithm>
using namespace std;
struct edge{
int e,next;
//double v;
};
edge edg[100005];
int n,m,head[105],in_degree[105],ans[105],cnt;
int main(){
memset(head,-1,sizeof(head));
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
edg[i].e=b;
edg[i].next=head[a];
head[a]=i;
in_degree[b]++;
//num[i]=999999999999999;
}
queue<int>que;
for(int i=1;i<=n;i++){
if(in_degree[i]==0){
que.push(i);
}
}
while(!que.empty()){
int temp=que.front();
que.pop();
ans[cnt++]=temp;
if(cnt==n){
for(int i=0;i<n;i++){
cout<<ans[i]<<" ";
}
cout<<endl;
return 0;
}
for(int i=head[temp];i!=-1;i=edg[i].next){
int e=edg[i].e;
in_degree[e]--;
if(in_degree[e]==0){
que.push(e);
}
}
}
cout<<"have loop"<<endl;
//cout<<"orz"<<endl;
return 0;
}
输出所有的拓扑排序
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,ans[105],in_degree[105],mark[105];
void func(int now,vector<vector<int> >edg){
if(now==n+1){
for(int i=1;i<=n;i++){
cout<<ans[i]<<" ";
}
cout<<endl;
return ;
}
for(int i=1;i<=n;i++){
if(in_degree[i]==0&&mark[i]==0){
ans[now]=i;
mark[i]=1;
for(int j=0;j<edg[i].size();i++){
in_degree[edg[i][j]]--;
}
func(now+1,edg);
for(int j=0;j<edg[i].size();j++){
in_degree[edg[i][j]]++;
}
mark[i]=0;
}
}
}
int main(){
//memset(head,-1,sizeof(head));
cin>>n>>m;
vector<vector<int> >edg(n+1,vector<int>());
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
edg[a].push_back(b);
in_degree[b]++;
//num[i]=999999999999999;
}
func(1,edg);
//cout<<"orz"<<endl;
return 0;
}
题目描述
人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别、函数逼近及贷款风险评估等诸多领域有广泛的应用。对神经网络的研究一直是当今的热门方向,兰兰同学在自学了一本神经网络的入门书籍后,提出了一个简化模型,他希望你能帮助他用程序检验这个神经网络模型的实用性。
在兰兰的模型中,神经网络就是一张有向图,图中的节点称为神经元,而且两个神经元之间至多有一条边相连,如果有一条边 X 的终点是第 i 号神经元,那么 X 即为该神经元的输入通道,如果有一条边 Y 的起点是第 i 号神经元,那么 Y 即为该神经元的输出通道,Ci 表示神经元目前的状态,Ui 是阈值,可视为神经元的一个内在参数。
神经元按一定的顺序排列,构成整个神经网络。在兰兰的模型之中,神经网络中的神经元分为几层;称为输入层、输出层,和若干个中间层。每层神经元只向下一层的神经元输出信息,只从上一层神经元接受信息。
兰兰规定,Ci 服从公式:
Ci=∑WjiCj−Ui ((j,i)∈E)
公式中的 Wji(可能为负值)表示连接 j 号神经元和 i 号神经元的边的权值。当 Ci 大于 0 时,该神经元处于兴奋状态,否则就处于平静状态。当神经元处于兴奋状态时,下一秒它会向其他神经元传送信号,信号的强度为Ci。
如此,在输入层神经元被激发之后,整个网络系统就在信息传输的推动下进行运作。现在,给定一个神经网络,及当前输入层神经元的状态(Ci),要求你的程序运算出最后网络输出层的状态。
输入
输入文件第一行是两个整数 n(1≤n≤100) 和 p。接下来 n 行,每行 2 个整数,第 i+1 行是神经元 i 最初状态(Ci)和其阈值(Ui),非输入层的神经元开始时状态必然为 0。再下面 P 行,每行由 2 个整数 i,j 及 1 个整数Wij,表示连接神经元 i,j 的边权值为 Wij。
输出
输出文件包含若干行,每行有 2 个整数,分别对应一个神经元的编号,及其最后的状态,2 个整数间以空格分隔。仅输出最后状态大于 0 的输出层神经元状态,并且按照编号由小到大顺序输出。
若输出层的神经元最后状态均为 0,则输出 “NULL”。
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<cstdio>
#include<algorithm>
using namespace std;
struct edge{
int e,v,next;
};
edge edg[10005];
int n,m,c[105],u[105],head[105],in_degree[105],out_degree[105]
int main(){
memset(head,-1,sizeof(head));
cin>>n>>m;
//vector<vector<int> >edg(n+1,vector<int>());
queue<int>que;
for(int i=1;i<=n;i++){
cin>>c[i]>>u[i];
if(c[i]!=0){
que.push(i);
}
//num[i]=999999999999999;
}
for(int i=0;i<m;i++){
int a,b,v;
cin>>a>>b>>v;
edg[i].e=b;
edg[i].v=v;
edg[i].next=head[a];
head[a]=i;
in_degree[b]++;
out_degree[a]++;
}
while(!que.empty()){
int temp=que.front();
que.pop();
for(int i=head[temp];i!=-1;i=edg[i].next){
int e=edg[i].e,v=edg[i].v;
in_degree[e]--;
if(c[temp]>0){
c[e]+=v*c[temp];
}
if(in_degree[e]==0){
que.push(e);
c[e]-=u[e];
}
}
}
int f=0;
for(int i=1;i<=n;i++){
if(out_degree[i]==0&&c[i]>0){
cout<<i<<" "<<c[i]<<endl;
f=1;
}
}
if(f==0){
cout<<"NULL"<<endl;
}
//cout<<"orz"<<endl;
return 0;
}