RE60pts,悬一关
查看原帖
RE60pts,悬一关
1128559
guoguo160楼主2024/12/14 16:05

Tarjan求强连通分量,RE on #6,#7,#9,#10 https://www.luogu.com.cn/record/194428602

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e4 + 10;
const int M = 5 * 1e3 + 10;

int n, m;
vector<int> e[N];
vector<pair<int, int> > scc;
int f[M];
int cost[N];
int earn[N];
int dfn[N];
bool ins[N];
int low[N];
stack<int> st;
int idx;
int money;

void dfs(int u) {
	dfn[u] = low[u] = ++idx;
	ins[u] = 1;
	st.push(u);
	for (auto v : e[u]) {
		if (!dfn[v]) {
			dfs(v);
			low[u] = min(low[u], low[v]);
		}
		else {
			if (ins[v])
				low[u] = min(low[u], dfn[v]);
		}
	}
	if (dfn[u] == low[u]) {
		int a, b;
		a = b = 0;
		while (1) {
			int j = st.top();
			a += cost[j];
			b += earn[j];
			ins[j] = 0;
			st.pop();
			if (j == u) break;
		}
		scc.push_back({a, b});
	}
}

signed main() {
	cin >> n >> m >> money;
	for (int i = 1; i <= n; ++i) {
		cin >> cost[i] >> earn[i];
	}
	for (int i = 1; i <= m; ++i) {
		int u, v;
		cin >> u >> v;
		if (u == v);
		else
			e[u].push_back(v), e[v].push_back(u);
	}
	for (int i = 1; i <= n; ++i) {
		if (!dfn[i]) {
			dfs(i);
		}
	}
	// cout<<"----------------------------\n";
	// cout<<scc.size()<<"\n";
	// for(auto j:scc){
	// 	cout<<j.first<<" "<<j.second<<"\n";
	// }
	// cout<<"---------------------------\n";
	for (int i = 1; i <= (int)scc.size(); ++i) {
		for (int j = money; j >= scc[i - 1].first; --j) {
			int a = scc[i - 1].first;
			int b = scc[i - 1].second;
			f[j] = max(f[j], f[j - a] + b);
		}
	}
	cout << f[money] << "\n";
	return 0;
}
2024/12/14 16:05
加载中...