• 【模板】Tarjan scc缩点


    代码如下

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main() {
    	ios::sync_with_stdio(0);
    	cin.tie(0), cout.tie(0);
    	int n, m;
    	cin >> n >> m;
    	vector<int> a(n + 1);
    	vector<vector<int>> adj(n + 1);
    	for(int i = 1; i <= n; i++) {
    		cin >> a[i];
    	}
    	for (int i = 1; i <= m; i++) {
    		int u, v;
    		cin >> u >> v;
    		adj[u].push_back(v);
    	}	
    	vector<int> dfn(n + 1), low(n + 1), scc(n + 1);
    	vector<vector<int>> has(1);
    	int dfn_cnt = 0, scc_cnt = 0;
    	stack<int> st;
    	function<void(int)> tarjan = [&](int u) {
    		dfn[u] = low[u] = ++dfn_cnt;
    		st.push(u);
    		for (int v : adj[u]) {
    			if (dfn[v] == 0) {
    				tarjan(v);
    				low[u] = min(low[u], low[v]);
    			} else if (scc[v] == 0) {
    				low[u] = min(low[u], dfn[v]);
    			}
    		}
    		if (low[u] == dfn[u]) {
    			++scc_cnt;
    			has.push_back(vector<int>());
    			while (1) {
    				int v = st.top();
    				st.pop();
    				scc[v] = scc_cnt;
    				has[scc_cnt].push_back(v);
    				if (v == u) {
    					break;
    				} 
    			}
    		}
    	};
    	for (int i = 1; i <= n; i++) {
    		if (dfn[i] == 0) {
    			tarjan(i);
    		}
    	}
    	vector<vector<int>> g(scc_cnt + 1);
    	vector<int> degree(scc_cnt + 1), b(scc_cnt + 1);
    	for (int i = 1; i <= scc_cnt; i++) {
    		for (auto x : has[i]) {
    			b[i] += a[x];
    		}
    	}
    	for (int u = 1; u <= n; u++) {
    		for (auto v : adj[u]) {
    			if (scc[u] != scc[v]) {
    				g[scc[u]].push_back(scc[v]);
    				++degree[scc[v]];
    			}
    		}
    	}
    	queue<int> q;
    	vector<int> f(scc_cnt + 1);
    	for (int i = 1; i <= scc_cnt; i++) {
    		if (degree[i] == 0) {
    			q.push(i);
    		}
    	}
    	while (!q.empty()) {
    		int u = q.front();
    		q.pop();
    		f[u] += b[u];
    		for (auto v : g[u]) {
    			f[v] = max(f[v], f[u]);
    			if (--degree[v] == 0) {
    				q.push(v);
    			}
    		}
    	}
    	cout << *max_element(f.begin(), f.end()) << endl;
    	return 0;
    } 
    
  • 相关阅读:
    window.fonts
    smpt authentification 配置
    如何从思维上应对
    中文字体 英文字体
    Path Breadcrumbs
    drupal commerce app
    做视频或者什么模块开发之类的
    分页符 箭头 难看
    theme wrapper 例子
    background position 稍微深入
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10544880.html
Copyright © 2020-2023  润新知