(精)(图论加强)(强连通图)

本文详细阐述了如何使用C语言实现深度学习算法,并通过实例展示了其应用过程。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <stack>
#define MAX 110
using namespace std;
typedef struct MAP{
	int to;
	MAP *next;
}MAP;
MAP *map[MAX],node[MAX*MAX];
int n,cou,ind,scc,sccf[MAX],low[MAX],numed[MAX];
int ins[MAX];
stack <int> s;
void init()
{
	int i;
	for(i=0; i<=n; i++)
		numed[i] = i;
	cou = scc = 0;
	ind = 1;
	memset(ins,0,sizeof(ins));
	memset(low,0,sizeof(low));
	memset(node,'/0',sizeof(node));
	memset(map,'/0',sizeof(map));
	memset(numed,0,sizeof(numed));
	memset(sccf,0,sizeof(sccf));
}
void input()
{
	int i,x;
	scanf("%d",&n);
	for(i=1; i<=n; i++)
	{
		while( scanf("%d",&x) && x )
		{
			node[cou].to = x;
			node[cou].next = map[i];
			map[i] = &node[cou++];
		}
	}
}
void Tarjan(int u)
{
	int v;
	low[u] = numed[u] = ind++;
	s.push(u);
	ins[u] = 1;
	MAP *head = map[u];
	while( head != NULL )
	{
		v = head->to;
		if( !numed[v] )
		{
			Tarjan(v);
			if( low[v] < low[u] )
				low[u] = low[v];
		}
		else
			if( ins[v] && numed[v] < low[u] )
				low[u] = numed[v];
		head = head->next;
	}
	if( numed[u] == low[u] )
	{
		scc++;
		do
		{
			v = s.top();
			s.pop();
			ins[v] = 0;
			sccf[v] = scc;
		}while( u != v );
	}
}
int Atask() // 找入度为0的点。 
{
	int indegree[MAX],ans = 0,i;
	MAP *head;
	memset(indegree,0,sizeof(indegree));
	for(i=1; i<=n; i++)
	{
		head = map[i];
		while( head != NULL )
		{
			if( sccf[i] != sccf[head->to] )
				indegree[sccf[head->to]]++;
			head = head->next;
		}
	}
	for(i=1; i<=scc; i++)
		if( indegree[i] == 0 )
			ans++;
	return ans;
}
int Btask()//找出度为0的点。 
{
	int outd[MAX],ans = 0,i;
	MAP *head;
	memset(outd,0,sizeof(outd));
	for(i=1; i<=n; i++)
	{
		head = map[i];
		while( head != NULL )
		{
			if( sccf[i] != sccf[head->to] )
				outd[sccf[i]]++;
			head = head->next;
		}
	}
	for(i=1; i<=scc; i++)
		if( outd[i] == 0 )
			ans++;
	return ans;
}
int main()
{
	int i,ansa,ansb;
	init();
	input();
	for(i=1; i<=n; i++)
		if( !numed[i] )
			Tarjan(i);
	if( scc == 1 ) // 特殊处理。 
		printf("1/n0/n");
	else
	{
		ansa = Atask();
		ansb = Btask();
		printf("%d/n%d/n",ansa,max(ansa,ansb));
	}
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值