Tarjan + Spfa 40pts WA 求调
查看原帖
Tarjan + Spfa 40pts WA 求调
667558
_Kamisato_Ayaka_楼主2024/11/11 17:09
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 2e5 + 10;
inline int read()
{
	int f = 1,res = 0;
	char ch = getchar();
	while(!isdigit(ch)){if(ch == '-') f = -1;ch = getchar();}
	while(isdigit(ch)){res = (res << 1) + (res << 3) + (ch ^ 48);ch = getchar();}
	return res * f;
}
int n,m,idx = 1,cur,sccnt,from[MAXN],to[MAXN],val[MAXN],dis[MAXN],val_sum[MAXN];
int head[MAXN],dfn[MAXN],low[MAXN],color[MAXN],Answer = INT_MIN;
bool vis[MAXN],flg[MAXN],vst[MAXN];
stack < int > st;
struct node{
	int v,nxt;
}edge[MAXN];
inline void add(int u,int v)
{
	edge[idx].v = v;
	edge[idx].nxt = head[u];
	head[u] = idx ++;
}
inline void tarjan(int u)
{
	dfn[u] = low[u] = ++ cur;
	st.push(u);
	vis[u] = 1;
	for(int i = head[u];i != -1;i = edge[i].nxt)
	{
		int v = edge[i].v;
		if(!dfn[v])
		{
			tarjan(v);	
			low[u] = min(low[u],low[v]);
		}
		else if(vis[v])
			low[u] = min(low[u],dfn[v]);
	}
	if(dfn[u] == low[u])
	{
		sccnt ++;
		int tmp = -1;
		while(tmp != u)
		{
			tmp = st.top();
			st.pop();
			vis[tmp] = 0;
			color[tmp] = sccnt;
			val_sum[sccnt] += val[tmp];
		}
	}
}
inline void spfa(int s)
{
	memset(dis,-0x3f,sizeof(dis));
	memset(vst,0,sizeof(vis));
	queue < int > q;
	dis[s] = val_sum[s];
	vst[s] = 1;
	q.push(s);
	while(!q.empty())
	{
		int u = q.front();
		q.pop();
		vst[u] = 0;
		for(int i = head[u];i != -1;i = edge[i].nxt)
		{
			int v = edge[i].v;
			if(dis[v] < dis[u] + val_sum[v])
			{
				dis[v] = dis[u] + val[v];
				if(!vst[v])
				{
					vst[v] = 1;
					q.push(v);
				}
			}
		}
	}
	for(int i = 1;i <= sccnt;i ++)
		Answer = max(Answer,dis[i]);
}

signed main()
{
	n = read(),m = read();
	memset(head,-1,sizeof(head));
	for(int i = 1;i <= n;i ++) val[i] = read(); 
	for(int i = 1;i <= m;i ++)
	{
		int u = read(),v = read();
		from[i] = u,to[i] = v;
		add(u,v);
	}
	for(int i = 1;i <= n;i ++)
	{
		if(!dfn[i]) tarjan(i);
	}
	memset(head,-1,sizeof(head));
	for(int i = 1;i <= idx + 33;i ++)
		edge[i].v = edge[i].nxt = 0;
	idx = 1;
	for(int i = 1;i <= m;i ++)
	{
		if(color[from[i]] != color[to[i]])
			add(color[from[i]],color[to[i]]);
	}
	for(int i = 1;i <= sccnt;i ++) spfa(i);
	printf("%lld\n",Answer);
	return 0;
}
2024/11/11 17:09
加载中...