社区讨论

40 pts 求调

P3387【模板】缩点参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mhjtknvl
此快照首次捕获于
2025/11/04 08:17
4 个月前
此快照最后确认于
2025/11/04 08:17
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;

int n, m, idx, idxb, tim, ans;
int head[10005], headb[10005], scc[10005], dfn[10005], low[10005], p[10005];
bool vis[10005];
int ind[10005], dis[10005];
stack<int> s;
queue<int> q;
struct edge{int from, to, ne;} e[100005], eb[100005];

void add(int u, int v)
{
	++idx;
	e[idx].from = u;
	e[idx].to = v;
	e[idx].ne = head[u];
	head[u] = idx;
}

void addb(int u, int v)
{
	++idxb;
	eb[idx].to = v;
	eb[idx].ne = headb[u];
	headb[u] = idxb;
}

void tarjan(int u)
{
	low[u] = dfn[u] = ++tim;
	s.push(u);
	vis[u] = 1;
	for (int i = head[u]; i; i = e[i].ne)
	{
		int v = e[i].to;
		if (!dfn[v])
		{
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if (vis[v])
			low[u] = min(low[u], low[v]);
	}
	if (dfn[u] == low[u])
	{
		while (!s.empty())
		{
			int v = s.top();
			s.pop();
			scc[v] = u;
			vis[v] = 0;
			if (u == v)
				break;
			p[u] += p[v];
		}
	}
	return;
}

void toposort()
{
	for (int i = 1; i <= n; ++i)
	{
		if (scc[i] == i && ind[i] == 0)
			q.push(i), dis[i] = p[i];
	}
	while (!q.empty())
	{
		int u = q.front();
		q.pop();
		for (int i = headb[u]; i; i = eb[i].ne)
		{
			int v = eb[i].to;
			dis[v] = max(dis[v], dis[u] + p[v]);
			--ind[v];
			if (ind[v] == 0)
				q.push(v); 
		}
	}
	for (int i = 1; i <= n; ++i)
		ans = max(ans, dis[i]);
	return;
}

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i)
		scanf("%d", p + i);
	for (int i = 1; i <= m; ++i)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v);
	}
	for (int i = 1; i <= n; ++i)
		if (!dfn[i])
			tarjan(i);
	for (int i = 1; i <= m; ++i)
	{
		int u = scc[e[i].from], v = scc[e[i].to];
		if (u != v)
		{
			addb(u, v);
			++ind[v];
		}
	}
	toposort();
	printf("%d\n", ans);
	return 0;
}

回复

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

正在加载回复...