70pts求调
查看原帖
70pts求调
1052511
XinFengIneverleft楼主2023/10/23 21:38

tarjan缩点+spfa
我寻思着都缩完点了应该不至于还T吧(
WA on #8-#10 #21-#25 #29-#31
TLE on #26-#28

#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#define PII pair<int,int>
using namespace std;

const int N = 100005;
vector<int> g[N];
vector<PII > h[N];

pair<int, PII > p[N];

stack<int> stk;
bool instk[N];
int dfn[N], low[N];
int timestamp, scc_cnt;
int id[N], size[N];

int dis[N], tt[N];
bool vis[N];
queue<int> q;

void add(int x, int y)
{
	g[x].push_back(y);
}

void tarjan(int u)
{
	dfn[u] = low[u] = ++timestamp;
	stk.push(u), instk[u] = true;

	for (int i = 0; i < (int)g[u].size(); i++)
	{
		int pos = g[u][i];
		if (!dfn[pos])
		{
			tarjan(pos);
			low[u] = min(low[u], low[pos]);
		}
		else if (instk[pos])
			low[u] = min(low[u], dfn[pos]);
	}

	if (dfn[u] == low[u])
	{
		int y;
		scc_cnt++;
		do
		{
			y = stk.top();
			stk.pop();
			instk[u] = false;
			id[y] = scc_cnt;
			size[scc_cnt]++;
		}
		while (y != u);
	}
}

bool spfa(int n)
{
	for (int i = 1; i <= n; i++)
		dis[i] = -0x3f3f3f3f;
	dis[0] = 0;

	q.push(0);
	vis[0] = true;

	while (!q.empty())
	{
		int pos = q.front();
		q.pop();
		vis[pos] = false;

		if (tt[pos] > n + 1)
			return true;

		for (int i = 0; i < (int)h[pos].size(); i++)
		{
			int to = h[pos][i].first;
			int val = h[pos][i].second;
			if (dis[to] < dis[pos] + val)
			{
				dis[to] = dis[pos] + val;
				if (!vis[to])
				{
					q.push(to);
					tt[pos]++;
					vis[to] = true;
				}
			}
		}
	}
	return false;
}

int main()
{
	int n, k;
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= k; i++)
	{
		int x, a, b;
		scanf("%d%d%d", &x, &a, &b);
		p[i].first = x;
		p[i].second.first = a;
		p[i].second.second = b;
	}

	for (int i = 1; i <= k; i++)
	{
		int x = p[i].second.first, y = p[i].second.second;
		if (p[i].first == 1)
			add(y, x), add(x, y);
		else if (p[i].first == 3)
			add(y, x);
		else if (p[i].first == 5)
			add(x, y);
	}

	for (int i = 1; i <= n; i++)
		if (!dfn[i])
			tarjan(i);

	for (int i = 1; i <= k; i++)
	{
		int x = p[i].second.first, y = p[i].second.second;
		if ((p[i].first == 2 || p[i].first == 4) && id[x] == id[y])
		{
			printf("-1");
			return 0;
		}
		else if (p[i].first == 2)
			h[id[x]].push_back(make_pair(id[y], 1));
		else if (p[i].first == 4)
			h[id[y]].push_back(make_pair(id[x], 1));
	}

	for (int i = 1; i <= scc_cnt; i++)
		h[0].push_back(make_pair(i, 1));

	long long ans = 0;
	if (spfa(scc_cnt))
	{
		printf("-1");
		return 0;
	}
	for (int i = 1; i <= scc_cnt; i++)
		ans += 1ll * dis[i] * size[i];

	printf("%lld", ans);
	return 0;
}
2023/10/23 21:38
加载中...