蒟蒻20分求调,希望大佬给一个不用拓扑排序的代码(好像写完就是逆拓扑?qwq)
查看原帖
蒟蒻20分求调,希望大佬给一个不用拓扑排序的代码(好像写完就是逆拓扑?qwq)
1037516
DreamTsinghua楼主2023/10/20 22:47
#include <bits/stdc++.h>

using namespace std ;

const int N = 5e5 + 10 ;

int n, m ;

int e[N], ne[N], h[N], hs[N], idx ;
int dfs[N], low[N] ;
int ti, scc_cnt ;

stack <int> stk ;
bool st[N] ;
int id[N], size[N] ;
int p[N] ;
int f[N] ;

void add(int h[], int a, int b) {
	e[idx] = b ;
	ne[idx] = h[a] ;
	h[a] = idx ++ ;
}

void tarjan(int u) {
	dfs[u] = low[u] = ++ ti ;
	stk.push(u), st[u] = 1 ;

	for (int i = h[u]; i != -1 ; i = ne[i]) {
		int j = e[i] ;
		if (!dfs[j]) {
			tarjan(j) ;
			low[u] = min(low[u], low[j]) ;
		} else if (st[j])
			low[u] = min(low[u], dfs[j]) ;
	}
	if (low[u] == dfs[u]) {
		int y ;
		++ scc_cnt ;

		do {

			y = stk.top() ;
			stk.pop() ;

			st[y] = 0 ;
			id[y] = scc_cnt ;
			size[scc_cnt] += p[y] ;// 加点权
		} while (y != u) ;
	}
}

int main() {
	cin >> n >> m ;

	memset(h, -1, sizeof h) ;
	memset(hs, -1, sizeof hs) ;

	int sum = 0 ;
	for (int i = 1 ; i <= n ; i ++)
		cin >> p[i], sum += p[i] ;


	for (int i = 1 ; i <= m ; i ++) {
		int a, b;
		cin >> a >> b ;
		add(h, a, b) ;
	}

	for (int i = 1 ; i <= n ; i ++)
		if (!dfs[i])
			tarjan(i) ;


	for (int i = 1; i <= n ; i ++)

		for (int i = 1 ; i <= n ; i ++) {
			for (int j = h[i] ; j != -1 ; j = ne[j]) {
				int k = e[j] ;
				int a = id[i], b = id[k] ;
				if (a != b)
					add(hs, a, b) ;// 建新图,在hs里面  
			}
		}
	int ans = 0 ;

	if (scc_cnt == 1) {
		cout << sum ;
		return 0 ; // 胡写的~
	}
	for (int i = scc_cnt ; i; i --) {
		if (!f[i])
			f[i] = size[i] ;

		for (int j = hs[i] ; j != -1 ; j = ne[j]) {
			int k = e[j] ;
			f[k] = max(f[k], f[i] + size[k]) ;
			ans = max(ans, f[k]) ;
		}
	}

	cout << ans ;
	return 0 ;
}
//写了一下午快要死了,崩溃
2023/10/20 22:47
加载中...