社区讨论

求Hack

P1262间谍网络参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@mhjoc7q8
此快照首次捕获于
2025/11/04 05:50
4 个月前
此快照最后确认于
2025/11/04 05:50
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
const int M = 2e5 + 5;
typedef long long ll;
const int inf = 0x3f3f3f3f;
int n, p, r;
vector <int> G[N];
struct node {
	int id, sum;
} a[N];
int dfn[N], low[N];
int scc[N], times = 0;
stack <int> st;
vector <int> G2[N];
int color_cnt = 0;
int allmn[N];
void Tarjan(int u) {
	dfn[u] = low[u] = ++times;
	st.push(u);
	for (int i : G[u]) {
		if (!dfn[i]) {
			Tarjan(i);
			low[u] = min(low[u], low[i]);
		} else if (!scc[i]) {
			low[u] = min(low[u], dfn[i]);
		}
	}
	if (low[u] == dfn[u]) {
		color_cnt++;
		int now;
		do {
			now = st.top();
			st.pop();
			scc[now] = color_cnt;
			allmn[color_cnt] = min(allmn[color_cnt], now);
		} while (now != u);
	}
}
int need[N];
int in[N];
int need2[N];
signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	cin >> n;
	cin >> p;
	memset(allmn, 0x3f, sizeof allmn);
	memset(need, 0x3f, sizeof need);
	for (int i = 1; i <= p; i++) {
		cin >> a[i].id >> a[i].sum;
	}
	cin >> r;
	for (int i = 1; i <= r; i++) {
		int x, y;
		cin >> x >> y;
		G[x].push_back(y);
//		G[y].push_back(x);
	}
	for (int i = 1; i <= n; i++) {
		if (dfn[i] == 0) Tarjan(i);
	}
	for (int i = 1; i <= n; i++) {
		for (int j : G[i]) {
			if (scc[i] != scc[j]) {
				G2[scc[i]].push_back(scc[j]);
				in[scc[j]]++;
			}
		}
		if (i <= p)
			need[scc[a[i].id]] = min(need[scc[a[i].id]], a[i].sum);
	}
	queue<int> q;
	for (int i = 1; i <= color_cnt; i++) {
		if (in[i] == 0 && need[i] != inf) {
			q.push(i);
			need2[i] = 1;
		}
	}
	while (q.size()) {
		int p = q.front();
		q.pop();
		for (int i : G2[p]) {
			need[i] = min(need[i], need[p]);
			need2[i] = 0;
			in[i]--;
			if (in[i] == 0) {
				q.push(i);
			}
		}
	}
	int flag = 0, havemn = inf;
	ll cnt = 0;
	for (int i = 1; i <= color_cnt; i++) {
		if (need[i] == inf) {
			havemn = min(havemn, allmn[i]);
			flag = 1;
		} else if (need2[i])cnt += need[i];
	}
	if (flag == 1) cout << "NO\n" << havemn << "\n";
	else {
		cout << "YES\n" << cnt << "\n";
	}
	return 0;
}

回复

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

正在加载回复...