每日一题7.2

P2863 [USACO06JAN] The Cow Prom S - 洛谷

算是一个tarjan的板子题

#include
#include
#include
#include
using namespace std;
const int N = 1e4 + 5;
int dfn[N], low[N], s[N],belong[N];
vector g[N];
int cnt, top, num, ans, flag;
bool ins[N];
void tarjan(int u)
{
	dfn[u] = low[u] = ++cnt;
	s[++top] = u;
	ins[u] = true;
	for (int v : g[u])
	{
		if (!dfn[v])//没有被tarjan过
		{
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if (ins[v])//已经被探索过又在栈内
		{
			low[u] = min(low[u], dfn[v]);//这个dfn或low都可以,写出dfn是为了和双向tarjan相似模板
		}
	}
	if (dfn[u] == low[u])
	{
		num++;//scc的数量
		flag = 0;
		while (1)
		{
			belong[s[top]] = num;//属于哪个scc
			ins[s[top]] = false;
			flag++;
			if (s[top--] == u)
			{
				if (flag > 1)
				ans++;
				break;
			}
		}
	}
}
int main()
{
	int n, k;
	cin >> n >> k;
	for (int i = 0; i < k; i++)
	{
		int u, v;
		cin >> u >> v;
		g[u].push_back(v);
	}
	for (int i = 1; i <= n; i++)
	{
		if (!dfn[i])
		{
			tarjan(i);
		}
	}
	//for (int i = 1; i <= n; i++)
	//{
	//	cout << i << " " << dfn[i] << " " << low[i] << " " << belong[i] << endl;
	//}
	cout << ans << endl;
	return 0;

}

你可能感兴趣的:(每日一题,图论,算法,c++)