zoukankan      html  css  js  c++  java
  • P3387 【模板】缩点

    link

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <unordered_set>
    #include <cstring>
    #include <queue>
    #include <stack>
    # define LL long long
    using namespace std;
    
    const int maxn = 10000 + 10;
    const int maxm = 100000 + 10;
    int w[maxn];
    int sccw[maxn];
    int ui[maxm];
    int vi[maxm];
    
    struct Edge {
    	int to;
    	int next;
    }e1[maxm],e2[maxm];
    
    int head1[maxn];
    int head2[maxn];
    int en1;
    int en2;
    
    void addEdge1(int from, int to) {
    	e1[en1].next = head1[from];
    	e1[en1].to = to;
    	head1[from] = en1++;
    }
    
    void addEdge2(int from, int to) {
    	e2[en2].next = head2[from];
    	e2[en2].to = to;
    	head2[from] = en2++;
    }
    
    int timer;
    int scc_num;
    int col[maxn];
    int dict[maxn];
    int low[maxn];
    stack<int> stk;
    int instack[maxn];
    
    int indeg[maxn];
    int dp[maxn];
    
    void tarjan(int u) {
    	stk.push(u);
    	instack[u] = 1;
    	++timer;
    	dict[u] = timer;
    	low[u] = timer;
    	for (int i = head1[u]; i != -1; i = e1[i].next) {
    		int v = e1[i].to;
    		if (dict[v] == -1) {
    			tarjan(v);
    			low[u] = min(low[u], low[v]);
    		}
    		else {
    			if (instack[v]) {
    				low[u] = min(low[u], dict[v]);
    			}
    		}
    	}
    	if (low[u] == dict[u]) {
    		++scc_num;
    		while (stk.top() != u) {
    			int t = stk.top();
    			stk.pop();
    			col[t] = scc_num;
    			sccw[scc_num] += w[t];
    			instack[t] = 0;
    
    		}
    		stk.pop();
    		instack[u] = 0;
    		col[u] = scc_num;
    		sccw[scc_num] += w[u];
    
    	}
    }
    
    int main() {
    	memset(head1, -1, sizeof(head1));
    	memset(head2, -1, sizeof(head2));
    	int n, m;
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
    	for (int i = 0; i < m; i++) {
    		scanf("%d%d", &ui[i], &vi[i]);
    		addEdge1(ui[i], vi[i]);
    	}
    	memset(dict, -1, sizeof(dict));
    	for (int i = 1; i <= n; i++) {
    		if (dict[i] == -1) {
    			tarjan(i);
    		}
    	}
    
    	vector<unordered_set<int>> added(scc_num + 1);
    	for (int i = 0; i < m; i++) {
    		if (col[ui[i]] == col[vi[i]]) continue;
    		int u = col[ui[i]];
    		int v = col[vi[i]];
    		if (added[u].find(v) != added[u].end()) continue;
    		added[u].insert(v);
    		addEdge2(u, v);
    		indeg[v]++;
    	}
    	queue<int> q;
    	int res = 0;
    	for (int i = 1; i <= scc_num; i++) {
    		if (indeg[i] == 0) {
    			q.push(i);
    			dp[i] = sccw[i];
    			res = max(res, dp[i]);
    		}
    	}
    
    	while (!q.empty()) {
    		int cur = q.front();
    		q.pop();
    		for (int i = head2[cur]; i != -1; i = e2[i].next) {
    			int v = e2[i].to;
    			dp[v] = max(dp[v], dp[cur] + sccw[v]);
    			res = max(res, dp[v]);
    			indeg[v]--;
    			if (indeg[v] == 0) q.push(v);
    		}
    	}
    
    	printf("%d", res);
    	return 0;
    }
    
  • 相关阅读:
    CSOL大灾变移植记录
    游戏设计技巧——对象信息封装
    Filament初探,全场景性能测试
    Godot从编辑器创建自定义场景类型对象
    Python中面向对象编程和内置方法的使用解析【转】
    python中使用xlrd、xlwt操作excel表格详解【转】
    Python第三方库xlrd/xlwt的安装与读写Excel表格【转】
    python实现以及所有排序大总结【转】
    Python下异常、模块、文件、数据储存-json等知识讲解【转】
    python文件系统详细介绍【转】
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/13169743.html
Copyright © 2011-2022 走看看