90pts WA on #7 kosaraju+toposort+dp 码风良好
查看原帖
90pts WA on #7 kosaraju+toposort+dp 码风良好
773659
Elysia11115480楼主2024/7/20 16:25
#include<bits/stdc++.h>
//luoguP3387
using namespace std;
typedef long long ll;

int n, m, u, v, maxq;//缩点后节点最大编号 
struct Pair{
	int u, v;
	bool operator==(const Pair &T)const{
		return u == T.u && v == T.v;
	}
	bool operator<(const Pair &T)const{
		if (u != T.u)
			return u < T.u;
		return v < T.v; 
	}
};
struct G{
	int u, v, nxt;
}e[200005], ef[200005], en[200005];//原图,反图,缩点后的图
map<Pair, int> mp; 
int head[100005], pos;//同上 
int headf[100005], posf;
int headn[100005], posn;
int dq[100005];//原点权 
int ndq[100005];//缩点后点权 
int qf[100005];//点i属于哪个强连通分量 
int dp[100005];
int r[100005];
vector<int> wd;//dfs序 
void addEdge(G *e, int *head, int &pos, int u, int v)
{
	e[++pos] = {u, v, head[u]};
	head[u] = pos;
}
bool vis[100005];
void dfs_f(int u)
{
	vis[u] = true;
	wd.push_back(u); 
	for (int i = headf[u];i;i = ef[i].nxt)
		if (!vis[ef[i].v])
			dfs_f(ef[i].v);
}
void dfs(int u, int k)
{
	vis[u] = true;
	qf[u] = k;
	ndq[k] += dq[u];
	for (int i = head[u];i;i = e[i].nxt)
		if (!vis[e[i].v])
			dfs(e[i].v, k);
}
void makeAns()
{
	//for (int i = 1;i <= maxq; ++i)
	//	printf("%d\n", ndq[i]);
	mp.clear();
	for (int i = 1;i <= pos; ++i)
	{
		int ku = e[i].u, kv = e[i].v;
		if (qf[ku] != qf[kv] && !mp[{qf[ku], qf[kv]}])
			addEdge(en, headn, posn, qf[ku], qf[kv]), mp[{qf[ku], qf[kv]}] = 1, ++r[qf[kv]]/*,
			printf("addEdge %d, %d\n", qf[ku], qf[kv])*/;
	}
	int ansi = 0;
	queue<int> q;
	for (int i = 1;i <= maxq; ++i)
		if (!r[i])
			q.push(i), dp[i] = ndq[i]/*, printf("Cls dp[%d] = %d\n", i, ndq[i])*/;
	while (q.size())
	{
		int c = q.front();
		q.pop();
		for (int i = headn[c];i;i = en[i].nxt)
		{
			int ku = en[i].u, kv = en[i].v;
			dp[kv] = max(dp[kv], dp[ku] + ndq[kv]);
			//printf("Update dp[%d]:to dp[%d](= %d) + %d\n", kv, ku, dp[ku], ndq[kv]);
			//printf("");
			--r[kv];
			if (!r[kv])
				q.push(kv);
		}
	}
	for (int i = 1;i <= maxq; ++i)
		ansi = max(ansi, dp[i])/*, printf("dp[%d] = %d\n", i, dp[i])*/;
	printf("%d", ansi);
}
int main()
{
	//freopen("a.in", "r", stdin);
	//freopen("my.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for (int i = 1;i <= n; ++i)
		scanf("%d", dq + i);
	for (int i = 1;i <= m; ++i){
		scanf("%d%d", &u, &v);
		if (u != v && !mp[{u, v}])
			addEdge(e, head, pos, u, v), addEdge(ef, headf, posf, v, u),
			mp[{u, v}] = 1;
	}
	for (int i = 1;i <= n; ++i)
		if (!vis[i])
			dfs_f(i);
	memset(vis, 0, sizeof(vis));
	for (int i = wd.size() - 1;i >= 0; --i)
		if (!vis[wd[i]])
			dfs(wd[i], ++maxq); 
	makeAns();
    return 0;
}

rt.

40pts->60pts->90pts

蒟蒻调不动了

玄关

求调

2024/7/20 16:25
加载中...