Popular Cows POJ - 2186(tarjan缩点)

题目:在zyh的高中,学生会每一年都会评选受欢迎学生,所谓受欢迎的学生,就是被所有学生喜欢的学生。 每个学生都喜欢自己,碰巧的是,如果学生A 喜欢学生B ,学生B喜欢学生C, 那么学生A也喜欢学生C。 但是学生A喜欢学生B 并不意味着学生B喜欢学生A。 zyh参与了评选工作,苦逼的他被安排去购买奖品,于是他拿到了一张表,这张表有m条记录,每条记录由两个数字a,b组成,表示a,喜欢b ,但是由于学生太多了,他无法知道会有多少个受欢迎的学生,从而无法去购买奖品,你能帮他解决吗?

水题,AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <stack>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
int x,y,n,m,head[maxn],tot,cnt,num,low[maxn],dfn[maxn],vis[maxn],belong[maxn],out[maxn];
struct node{
	int v,nxt;
}e[maxn];
void init(){
	memset(head,-1,sizeof(head));
	memset(low,0,sizeof(low));
	memset(dfn,0,sizeof(dfn));
	memset(vis,0,sizeof(vis));
	memset(out,0,sizeof(out));
	memset(belong,0,sizeof(belong));
	tot=1;
	cnt=0;
	num=0;
}
void add(int u,int v){
	e[tot].v=v;
	e[tot].nxt=head[u];
	head[u]=tot++;
}
stack<int>s;
void tarjan(int u){
	low[u]=dfn[u]=++cnt;
	s.push(u);
	vis[u]=1;
	for(int i=head[u];i!=-1;i=e[i].nxt){
		int v=e[i].v;
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[v],low[u]);
		}
		else if(vis[v])low[u]=min(dfn[v],low[u]);
	}
	if(dfn[u]==low[u]){
		num++;
		int v;
		do{
			v=s.top();
			s.pop();
			vis[v]=0;
			belong[v]=num;
		}while(u!=v);
	}
}
void dfs(int u){
	vis[u]=1;
	for(int i=head[u];i!=-1;i=e[i].nxt){
		int v=e[i].v;
		if(belong[u]!=belong[v]){
			out[belong[u]]++;
		}
		if(!vis[v])dfs(v);
	}
}
int main(){
	init();
	cin>>n>>m;
	while(m--){
		//int x,y;
		cin>>x>>y;
		add(x,y);
	}
	for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++)if(!vis[i])dfs(i);
	int res=0;
	for(int i=1;i<=num;i++){
		if(out[i]==0){
			if(res==0)res=i;
			else{
				res=0;//如果缩点以后还有两个答案,那么说明原图不连通,那肯定无法呗被所有奶牛仰慕啊 
				break;
			}
		}
	}
	if(!res)cout<<0;
	else{
		int ans=0;
		for(int i=1;i<=n;i++)if(belong[i]==res)ans++;
			cout<<ans;
	} 
}
原创文章 38 获赞 7 访问量 1755

猜你喜欢

转载自blog.csdn.net/Alanrookie/article/details/105953885
今日推荐