42pts 求调
查看原帖
42pts 求调
481621
Zhang_Wenjie楼主2024/7/30 23:45

感谢 dalao

#include <bits/stdc++.h>
#define re register int 

using namespace std;
const int N = 1e5 + 10, M = 3e5 + 10;

struct Edge
{
	int to, next;
}e[M];
int top, h[N];
int dfn[N], low[N], idx, scc[N], cnt, siz[N];
int n, m, in[N];
bool st[N];

stack<int> stk;
vector<int> g[N];
map<pair<int, int>, bool> mp;

inline void add(int x, int y)
{
	e[++ top] = (Edge){y, h[x]};
	h[x] = top;
}

void tarjan(int u)
{
	low[u] = dfn[u] = ++ idx;
	st[u] = true;
	stk.push(u);
	
	for (re i = h[u]; i; i = e[i].next)
	{
		int v = e[i].to;
		if (!dfn[v])
		{
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if (st[v])
			low[u] = min(low[u], dfn[v]);
	}
	if (low[u] == dfn[u])
	{
		cnt ++;
		int ver;
		do
		{
			ver = stk.top(); stk.pop();
			st[ver] = false;
			scc[ver] = cnt;
			siz[cnt] ++;
		}while (ver != u);
	} 
}

int main()
{	
	scanf("%d %d", &n, &m);
	while (m --)
	{
		int x, y; scanf("%d %d", &x, &y);
		add(x, y);
	}
	for (re i = 1; i <= n; i ++)
		if (!dfn[i]) tarjan(i);
		
//	for (re i = 1; i <= n; i ++) 
//		cout << i << "in " << scc[i] << '\n';
	
	for (re u = 1; u <= n; u ++)
		for (re j = h[u]; j; j = e[j].next)
		{
			int v = e[j].to;
			if (scc[u] != scc[v] && !mp.count({scc[u], scc[v]})) 
			{
				in[scc[v]] ++;
				g[scc[u]].push_back(scc[v]);
				
				mp[{scc[u], scc[v]}] = true;
			}
		}
	int p = 0;
	for (re i = 1; i <= cnt; i ++)
		if (!in[i])
		{
			p ++;
			if (siz[i] > 1) continue;
			bool flag = false;
			
//			cout << i << '\n';
		
			for (re j = 0; j < g[i].size(); j ++)
			{
				int v = g[i][j];
				if (in[v] == 1) 
				{
					flag = true;
					break;
				}
			}
			if (!flag) p --;
		}
	
	printf("%.6lf\n", (double)(n - p) / (double)n);
	
	return 0;
}
2024/7/30 23:45
加载中...