92分求调
查看原帖
92分求调
837114
idiotgoose楼主2023/10/6 15:23
92分。建图是a喜欢b则边b->a,tarjin缩点后dp找可达点集sz为n的scc,找不到则输出0。
//#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<string.h>
#include<set>
using namespace std;
const int INF = 1e9;
const int maxn = 10000 + 5;
vector<int> G[maxn];
int pre[maxn];
int lowlink[maxn];
int sccno[maxn];
int dfs_clock;
int scc_cnt;
int scc[maxn];
int n;//点数
stack<int> S;
void dfs(int u)
{
	pre[u] = lowlink[u] = ++dfs_clock;
	S.push(u);
	for (int i = 0; i < G[u].size(); i++)
	{
		int v = G[u][i];
		if (!pre[v])
		{
			dfs(v);
			lowlink[u] = min(lowlink[u], lowlink[v]);
		}
		else if (!sccno[v])
		{
			lowlink[u] = min(lowlink[u], pre[v]);
		}
	}
	if (lowlink[u] == pre[u])
	{
		scc_cnt++; scc[scc_cnt] = 0;
		for (;;)
		{
			int v = S.top(); S.pop();
			sccno[v] = scc_cnt;
			scc[scc_cnt]++;
			if (v == u)break;
		}
	}
}
void find_scc()
{
	memset(pre, 0, sizeof(pre));
	memset(sccno, 0, sizeof(sccno));
	dfs_clock = scc_cnt = 0;
	for (int i = 1; i <= n; i++)
	{
		if (!pre[i])dfs(i);
	}
}
int u0[50000 + 5];
int v0[50000 + 5];
int sz[maxn];
set<int> graph[maxn];
int dp(int u)
{
	int& ans = sz[u];
	if (ans > 0)return ans;
	ans = scc[u];
	for (auto a : graph[u])
	{
		ans += dp(a);
	}
	return ans;
}
int main()
{
	int m; cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		int a, b;
		cin >> a >> b;
		u0[i] = a; v0[i] = b;
		G[b].push_back(a);
	}
	find_scc();
	for (int i = 0; i < m; i++)
	{
		int a = sccno[u0[i]];
		int b = sccno[v0[i]];
		if (a != b)
		{
			graph[b].insert(a);
		}
	}
	int ans = 0;
	for (int i = 1; i <= scc_cnt; i++)
	{
		if (!sz[i])dp(i);
		if (sz[i] == n)ans=scc[i];
	}
	cout << ans;
	
	return 0;
}
2023/10/6 15:23
加载中...