poj 1236 Network of Schools

题目链接Network of Schools

题意 :给你一个学校的单向连通图,1:问你至少选几个学校发放软件才能使全部学校都收到,2:问你至少添加几条边才能使全部的学校够成一个强连通分量

题解:求出强连通分量个数,然后找到强量通分量入度为0的个数res,这是第一个的答案(注意只有一个强连通分量的情况),然后找到出度为0的强连通分量个数res1,max(res,res1)就是答案;

//#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<vector>
#define pb push_back
#define ll long long
#define PI 3.14159265
using namespace std;
const int maxn=1e2+5;
vector<int>g[maxn];
vector<int>rg[maxn];
vector<int>vs;
bool vis[maxn];
bool out[maxn];
int cmp[maxn]; 
int N,M; 
void dfs(int v)
{
	vis[v]=true;
	for(int i=0;i<g[v].size();i++)
	{
		if(!vis[g[v][i]])dfs(g[v][i]);
	}
	vs.pb(v);
}
void rdfs(int v,int k)
{
	vis[v]=true;
	cmp[v]=k;
	for(int i=0;i<rg[v].size();i++)
	{
		if(!vis[rg[v][i]])rdfs(rg[v][i],k);
	}
}
int scc()
{
	for(int i=1;i<=N;i++)
	{
		if(!vis[i])dfs(i);
	}
	memset(vis,false,sizeof(vis));
	int k=0; 
	for(int i=vs.size()-1;i>=0;i--)
	{
		if(!vis[vs[i]])rdfs(vs[i],k++);
	} 
	return k;
}
int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>N;
	for(int i=1;i<=N;i++)
	{
		int a;
		while(cin>>a) 
		{
			if(!a)break;
			g[i].pb(a);
			rg[a].pb(i);
		}
	}
	int n=scc();
	memset(vis,false,sizeof(vis));
	for(int i=1;i<=N;i++)
	{
		for(int j=0;j<g[i].size();j++)
		{
			if(cmp[g[i][j]]!=cmp[i])
			{
				vis[cmp[g[i][j]]]=true;
				out[cmp[i]]=true;
			}
		}
	}
	int res=0,res1=0;
	for(int i=0;i<n;i++)
	{
		if(!vis[i])res++;
		if(!out[i])res1++;
	}
	res1=max(res,res1);
	res=res>0?res:1;
	if(n==1)res1=0;
	cout<<res<<'\n'<<res1<<'\n'; 
	return 0;
 } 
posted @ 2017-10-12 22:13  lhclqslove  阅读(108)  评论(0编辑  收藏  举报