POJ 1236 Network of Schools 强连通分量Kosaraju

题意:有n(2 <= n <= 100)所学校,一个学校可以给另一个学校发送软件,软件可以传递a->b->c这样只要a学校安装了软件,那么b,c学校也就可以通过a安装软件,先在告诉你个学校之间的关系,第一个问题,问需要最少给多少个学校安装软件所有的学校就都能装上软件了,第二个问题,问添加最少多少个关系可以使得一个学校安装软件所有学校就都能安装上软件了。

想法:如果有一个组学校,他们之间可以相互发送要安装的软件,那么显然不管是谁先安装这个组里的其它学校都能够安装。所以可以使用强连通算法进行缩点,在缩完点之后,可以想到给入度为0的几组组学校发送安装软件那么其它的学校也就必然可以安装了。对于第二个问题,实际上就是,添加最少的边使得原图变为一个强连通图,对于学校组A->B->C->D,我只要将加上D->A这一条边那么A,B,C,D组学校就变成强连通分量了。所以我可以只关心出度为0的连通分量向入度为0的连通分量加一条边即可。比如A->B, A->C, D现在有这四个连通分量可以增加边B->D->A,C->A共三条边。所以增加的边的个数是出度为0的点的数量和入度为0的点的数量中的最大值。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<stack>
using namespace std;
int N;
bool vis[105];
stack<int>s;
int paint[105];
int col;
struct Edge{//边 
	int v;
	int w;
	struct Edge *next; 
};
struct FirstNode{//起始点 
	struct Edge *fstedge;
};

class AdjList{
	public:
		FirstNode *adjlist;
	public:
		AdjList(int num); 
		~AdjList()
		{
			delete[] adjlist;
		}
		void _init();
		void AddEdge(int u, int v, int w);
		void AddEdge(int u, int v);
	private:
		int num_node;//图中点的数量 
}; 
AdjList G_1(100);
AdjList G_2(100);

AdjList::AdjList(int num)
{
	num_node = num;
	FirstNode *temp_adjlist = new FirstNode[num_node + 1];
	adjlist = temp_adjlist;
	temp_adjlist = NULL;
	delete[] temp_adjlist;
}

void AdjList::_init()
{
	for(int i = 1; i <= num_node; i++)
	{
		adjlist[i].fstedge = NULL;
	}
}

void AdjList::AddEdge(int u, int v, int w)
{
	struct Edge *newEdge;
	newEdge = (Edge*)malloc(sizeof(Edge));
	newEdge->v = v;
	newEdge->w = w;
	newEdge->next = adjlist[u].fstedge;
	adjlist[u].fstedge = newEdge;
}

void AdjList::AddEdge(int u, int v)
{
	struct Edge *newEdge;
	newEdge = (Edge*)malloc(sizeof(Edge));
	newEdge->v = v;
	newEdge->next = adjlist[u].fstedge;
	adjlist[u].fstedge = newEdge;
}
void dfs_1(int u)
{
	vis[u] = true;
	for(Edge *p = G_1.adjlist[u].fstedge; p != NULL; p = p->next)
	{
		int v = p->v;
		if(!vis[v])
		{
			dfs_1(v);
		}
	}
	s.push(u);
}

void dfs_2(int u)
{
	vis[u] = true;
	for(Edge *p = G_2.adjlist[u].fstedge; p != NULL; p = p->next)
	{
		int v = p->v;
		if(!vis[v])
		{
			paint[v] = col;
			dfs_2(v);
		}
	} 
}

int get_max(int x, int y)
{
	if(x > y) return x;
	else return y;
}
void Get_Ans()
{
	int fst_ans = 0;
	int sec_ans = 0;
	int indegree[105];
	int outdegree[105];
	memset(indegree, 0, sizeof(indegree));
	memset(outdegree, 0, sizeof(outdegree));
	for(int i = 1; i <= N; i++)
	{
		int u = i;
		for(Edge *p = G_1.adjlist[u].fstedge; p != NULL; p = p->next)
		{
			int v = p->v;
			if(paint[u] != paint[v])
			{
				++indegree[paint[v]];
				++outdegree[paint[u]];
			}
		} 
	}
	
	for(int i = 1; i <= col; i++)
	{
		if(indegree[i] == 0) ++fst_ans;
		if(outdegree[i] == 0) ++sec_ans;
	}
	cout<<fst_ans<<endl<<get_max(fst_ans, sec_ans)<<endl;
}
int main()
{
	while(cin>>N)
	{
		G_1._init();
		G_2._init();
		for(int i = 1; i <= N; i++)
		{
			while(true)
			{
				int k;
				cin>>k;
				if(k == 0) break;
				G_1.AddEdge(i, k);
				G_2.AddEdge(k, i);
			}
		}
	
		col = 0;
		memset(paint, 0, sizeof(paint));
		memset(vis, false, sizeof(vis));
		while(!s.empty()) s.pop();
		for(int i = 1; i <= N; i++)
		{
			if(!vis[i])
			{
				dfs_1(i);
			}
		}
		memset(vis, false, sizeof(vis));
		while(!s.empty())
		{
			int u = s.top();
			s.pop();
			if(!vis[u])
			{
				++col;
				paint[u] = col;
				dfs_2(u);
			}
		}
		if(col == 1) cout<<"1"<<endl<<"0"<<endl;
		else Get_Ans();
	}
	return 0;
}

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值