图论-连通分量-入门-POJ1236 Network of Schools

没有考虑到原图本身就是强连通图的情况,此时缩点以后只有一个点,虽然出入度都是0,但全图已经联通,无须加边。
日后对问题进行转化了以后应该注意特殊情况。

#include<cstdio>
#include<iostream>
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,r,l) for(int i=(r);i>=(l);i--)
#define random(l,r) ((l)+rand()%((r)-(l)+1))
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
const int inf=1e9+10,N=110,M=10010;
const double eps=1e-6;
int n,rudu[N],chudu[N],ans1,ans2;
int nxt[M],h[N],to[M],l;
int low[N],dfn[N],tme;
int col[N],bianhao,mystack[N],top;
bool vis[N],instack[N];
void addedge(int a,int b){ nxt[++l]=h[a]; h[a]=l; to[l]=b; }
void tarjan(int v){
	dfn[v]=low[v]=++tme;
	vis[v]=instack[v]=true;
	mystack[++top]=v;
	for(int i=h[v];i!=0;i=nxt[i]){
		int u=to[i];
		if(!vis[u]){
			tarjan(u);
			low[v]=min(low[v],low[u]);
		}else if(instack[u]) low[v]=min(low[v],dfn[u]);
	}
	if(dfn[v]==low[v]){
		col[v]=++bianhao;
		instack[v]=false;
		while(mystack[top]!=v){
			int t=mystack[top];
			col[t]=bianhao;
			instack[t]=false;
			top--;
		}
		top--;
	}
}
int main(){
	ios::sync_with_stdio(false); cin.tie(0);
	cin>>n;
	rep(i,1,n){
		int a;
		cin>>a;
		while(a!=0){
			addedge(i,a);
			cin>>a;
		}
	}
	rep(i,1,n) if(!vis[i]) tarjan(i);
	rep(v,1,n) for(int i=h[v];i!=0;i=nxt[i]){
		if(col[v]!=col[to[i]]){
			chudu[col[v]]++;
			rudu[col[to[i]]]++;
		}
	}
	if(bianhao==1){//要考虑缩点之后只有一个点的情况,此时全图已经是连通图 ,无须加边。 
		cout<<1<<endl<<0;
		return 0;
	}
	rep(i,1,bianhao){
		if(rudu[i]==0) ans1++;
		if(chudu[i]==0) ans2++;
	}	
	cout<<ans1<<endl<<max(ans1,ans2);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值