蒟蒻求助缩点分层图板子
查看原帖
蒟蒻求助缩点分层图板子
503792
Svemit楼主2023/10/3 21:49

rt, 自己写了一个tle了看题解发现有个跟自己一样做法的交一发发现过了,调自己的死活过不了。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 2e5 + 5, M = 1e5 + 5, INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
int n, m;
int h[N], nxt[M], to[M], cnt;
int dfn[N], low[N], tim, bel[N], siz[N], scc_cnt;
stack<int> s;
bool ins[N], st[N];
vector<int> e[N];
int dist[N];
void add(int u, int v) {
	to[++ cnt] = v, nxt[cnt] = h[u], h[u] = cnt;
}
void tarjan(int u) {
	dfn[u] = low[u] = ++ tim;
	s.push(u), ins[u] = true;
	for(int i = h[u]; i; i = nxt[i]) {
		int v = to[i];
		if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
		else if(ins[v]) low[u] = min(low[v], dfn[v]);
	}
	if(dfn[u] == low[u]) {
		scc_cnt ++;
		int v;
		do {
			v = s.top(), s.pop();
			ins[v] = false;
			bel[v] = scc_cnt;
			siz[scc_cnt] ++;
		} while(v != u);
	}
}
void spfa(int s) {
	queue<int> q;
	q.push(s);
	st[s] = true;
	while(q.size()) {
		int u = q.front();
		for(auto v : e[u]) if(dist[v] < dist[u] + siz[u]) {
			dist[v] = dist[u] + siz[u];
			if(!st[v]) q.push(v);
			st[v] = true;
		}
		q.pop();
		st[u] = false;
	}
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
	cin >> n >> m;
	while(m --) {
		int u, v;
		cin >> u >> v;
		add(u, v);
	}
	for(int i = 1; i <= n; i ++) 
		if(!dfn[i]) tarjan(i);
	if(scc_cnt == 1) {
		cout << n << '\n';
		return 0;
	}
	for(int i = 1; i <= scc_cnt; i ++) siz[i + scc_cnt] = siz[i];
	for(int u = 1; u <= n; u ++)
		for(int i = h[u]; i; i = nxt[i]) {
			int v = to[i];
			if(bel[u] == bel[v]) continue;
			e[bel[u]].push_back(bel[v]);
			e[bel[v]].push_back(bel[u] + scc_cnt);
			e[bel[u] + scc_cnt].push_back(bel[v] + scc_cnt);
		}
	spfa(bel[1]);
	cout << dist[bel[1] + scc_cnt] << '\n';
    return 0;
}
2023/10/3 21:49
加载中...