SPFA + Tarjan,样例寄
查看原帖
SPFA + Tarjan,样例寄
524911
PassName楼主2024/9/22 12:40

RT,过不了样例。不知道哪里有问题。

#include <bits/stdc++.h>

#define rint register int
#define int long long
#define endl '\n'

using namespace std;

const int N = 1e6 + 5;
const int M = N << 1;

int n, m;
int h[N], e[M], ne[M], idx;
int dist[N];
int hc[N], vc[M], nc[M], tc, w[M];
int stk[N], ins[N], c[N], dfn[N], low[N];
vector<int> scc[N];
bool v[N];
int top, num, cnt;

void add(int a, int b)
{
	e[++idx] = b, ne[idx] = h[a], h[a] = idx;
}

void add_c(int a, int b, int c)
{
	vc[++tc] = b, nc[tc] = hc[a], hc[a] = tc, w[tc] = c;
}

void tarjan(int x)
{
	dfn[x] = low[x] = ++num;
	stk[++top] = x, ins[x] = 1;
	for (rint i = h[x]; i; i = ne[i])
	{
		int y = e[i];
		if (!dfn[y])
		{
			tarjan(y);
			low[x] = min(low[x], low[y]);
		}
		else if (ins[y]) low[x] = min(low[x], dfn[y]);
	}
	if (dfn[x] == low[x])
	{
		cnt++; int y;
		do
		{
			y = stk[top--], ins[y] = 0;
			c[y] = cnt, scc[cnt].push_back(y);
		} while (x != y);
	}
}

void SPFA(int s)
{
    queue<int> q;	
	memset(v, 0, sizeof v);
	v[s] = 1;
	dist[s] = 0;
	q.push(s);
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		v[x] = 0;
		for (rint i = hc[x]; i; i = nc[i])
		{
			int y = vc[i];
			int z = w[i];
			if (dist[y] < dist[x] + z)
			{
				dist[y] = dist[x] + z;
				if (!v[y])
				{
					v[y] = 1;
				    q.push(y);
				}
			}
		}
	}
}

signed main()
{
	cin >> n >> m;
	for (rint i = 1; i <= m; i++)
	{
	    int x, y;
		cin >> x >> y;
		add(x, y);
		add(x + n, y + n);
		add(y, x + n);
	} 
	for (rint i = 1; i <= 2 * n; i++)
	    if (!dfn[i])
	        tarjan(i);
	for (rint x = 1; x <= 2 * n; x++)
	{
		for (rint i = h[x]; i; i = ne[i])
		{
			int y = e[i];
			if (c[x] == c[y]) continue;
			add_c(c[x], c[y], scc[y].size());
		} 
	}
	SPFA(c[1]);
	cout << max(dist[c[1]], dist[c[n + 1]]) << endl;
	return 0;
}
2024/9/22 12:40
加载中...