社区讨论

蒟蒻分层图help

P3119[USACO15JAN] Grass Cownoisseur G参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo7xrx5c
此快照首次捕获于
2023/10/27 09:30
2 年前
此快照最后确认于
2023/10/27 09:30
2 年前
查看原帖
tarjan + 缩点挂掉了,求help
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
struct Edge {
	int to, next;
} e[maxn << 1];
int ecnt;
int head[maxn];
void addEdge(int u, int v) {
	e[++ecnt].to = v;
	e[ecnt].next = head[u];
	head[u] = ecnt;
}

int n;
int m;
int dfn[maxn];
int low[maxn];
int timer;
int scc_cnt;
vector<int> scc[maxn];
int sccno[maxn];
int scc_size[maxn << 1];
int d[maxn << 1];
stack<int> S;
bool in_stack[maxn];

void tarjan(int u) {
	dfn[u] = low[u] = ++timer;
	S.push(u);
	in_stack[u] = true;
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].to;
		if (dfn[v] == 0) {
			tarjan(v);
			low[u] = min(low[u], low[v]);
		} else if (in_stack[v]) {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (low[u] == dfn[u]) {
		scc_cnt++;
		while (!S.empty()) {
			int now = S.top();
			S.pop();
			scc_size[scc_cnt]++;
			scc[scc_cnt].push_back(now);
			sccno[now] = scc_cnt;
			in_stack[now] = false;
			if (now == u) break;
		}
	}
}

Edge new_edge[maxn << 2];
int new_ecnt;
int new_head[maxn << 1];
void addNewEdge(int u, int v) {
	new_edge[++new_ecnt].to = v;
	new_edge[new_ecnt].next = new_head[u];
	new_head[u] = new_ecnt;
}

queue<int> Q;
bool in_queue[maxn << 1];

void topsort() {
	in_queue[sccno[1]] = true;
	Q.push(sccno[1]);
	while (!Q.empty()) {
		int u = Q.front();
		for (int i = new_head[u]; i; i = new_edge[i].next) {
			int v = new_edge[i].to;
			if (d[u] + scc_size[u] > d[v]) {
				d[v] = d[u] + scc_size[u];
				if (!in_queue[v]) {
					in_queue[v] = true;
					Q.push(v);
				}
			}
		}
		in_queue[u] = false;
		Q.pop();
	}
}

int main() {
	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		int u, v;
		cin >> u >> v;
		addEdge(u, v);
	}
	for (int i = 1; i <= n; i++) {
		if (dfn[i] == 0) {
			tarjan(i);
		}
	}
	for (int u = 1; u <= n; u++) {
		for (int i = head[u]; i; i = e[i].next) {
			int v = e[i].to;
			if (sccno[u] != sccno[v]) {
				addNewEdge(sccno[u], sccno[v]);
				addNewEdge(sccno[u] + scc_cnt, sccno[v] + scc_cnt);
				addNewEdge(sccno[v], sccno[u] + scc_cnt);
			}
		}
	}
	if (scc_cnt == 1) {
		cout << n << endl;
		return 0;
	}
	topsort();
	cout << d[sccno[1] + scc_cnt] << endl;
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...