luogu2341 [HAOI2006]受欢迎的牛

题目大意

  每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你算出有多少头奶牛可以当明星。

思路

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#include <cassert>
using namespace std;

const int MAX_NODE = 10010;

struct Block
{
	int Size;
	bool NotLeaf;
}_blocks[MAX_NODE];
int _blockCnt;

struct Node
{
	int Low, DfsN;
	bool InStack;
	vector<Node*> Next;
	Block* BlockIn;
}_nodes[MAX_NODE];
int _vCount, DfsCnt;
stack<Node*> St;


void PopStack(Node *cur)
{
	Block *curBlock = _blocks + ++_blockCnt;
	Node *temp;
	do {
		temp = St.top();
		temp->InStack = false;
		St.pop();
		temp->BlockIn = curBlock;
		curBlock->Size++;
	} while (temp != cur);
}

void Dfs(Node *cur)
{
	cur->Low = cur->DfsN = ++DfsCnt;
	cur->InStack = true;
	St.push(cur);
	for (unsigned int i = 0; i < cur->Next.size(); i++)
	{
		if (!cur->Next[i]->DfsN)
		{
			Dfs(cur->Next[i]);
			cur->Low = min(cur->Low, cur->Next[i]->Low);
		}
		else if (cur->Next[i]->InStack)
			cur->Low = min(cur->Low, cur->Next[i]->DfsN);
	}
	if (cur->Low == cur->DfsN)
		PopStack(cur);
}

void Tarjan()
{
	for (int i = 1; i <= _vCount; i++)
	{
		if (!_nodes[i].DfsN)
			Dfs(_nodes + i);
		assert(St.size() == 0);
	}
}

int GetLeafCnt()
{
	int leafCnt = 0;
	for (int i = 1; i <= _vCount; i++)
		for (unsigned int j = 0; j < _nodes[i].Next.size(); j++)
			if (_nodes[i].BlockIn != _nodes[i].Next[j]->BlockIn)
				_nodes[i].BlockIn->NotLeaf = true;
	for (int i = 1; i <= _blockCnt; i++)
		leafCnt += !_blocks[i].NotLeaf;
	return leafCnt;
}

int GetAns()
{
	for (int i = 1; i <= _blockCnt; i++)
		if (!_blocks[i].NotLeaf)
			return _blocks[i].Size;
	return -1;
}

int main()
{
	int totEdge;
	scanf("%d%d", &_vCount, &totEdge);
	for (int i = 1; i <= totEdge; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		_nodes[u].Next.push_back(_nodes + v);
	}
	Tarjan();
	int leafCnt = GetLeafCnt();
	if (leafCnt > 1)
		printf("0
");
	else
		printf("%d
", GetAns());
	return 0;
}

  

原文地址:https://www.cnblogs.com/headboy2002/p/9391840.html