社区讨论

可爱萌新不会tarjan 求调

P3275[SCOI2011] 糖果参与者 4已保存回复 7

讨论操作

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

当前回复
7 条
当前快照
1 份
快照标识符
@lylfap96
此快照首次捕获于
2024/07/14 18:38
2 年前
此快照最后确认于
2024/07/14 20:20
2 年前
查看原帖
CPP
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#define orz %
#define ll long long
#define juruo Optimist_Skm
#define mid = (l + r) >> 1;
#define pii std::pair<int, int>
#define fi first
#define se second

namespace Fast_Skm {

	template <typename T>
	inline void read(T &x)
	{
		int s = 0, w = 1;
 		char c = getchar();
		while(!isdigit(c)) {
			if(c == '-')  w  = -1;
			c = getchar();
		}
		while(isdigit(c))
			s = (s << 1) + (s << 3) + (c ^ 48), c = getchar();
			
		x = s * w;
		return ;
	}


	template <typename T, typename... Arp>
	inline void read(T &x, Arp &...arp) {
		read(x), read(arp...);
        return ;
	}

	template <typename T>
	inline void write(T x)
	{
		if(x < 0) x = -x, putchar('-');
		int p = 0;
		char s[100];
		do {
			s[++p] = x % 10 + '0', x /= 10;
		} while (x);
		while(p) putchar(s[p--]);
		putchar(' ');
	}


	template <typename T, typename... Arp>
	inline void write(T &x, Arp &...arp) {
		write(x), write(arp...);
		return ;
	}

	template <typename S, typename T>
	inline void smax(S &x, T y) {
		x = (x > y) ? x : y;
	}

	template <typename S, typename T>
	inline void smin(S &x, T y) {
		x = (x < y) ? x : y;
	}

	inline void quit() {
		exit(0);
		return ;
	}

} using namespace Fast_Skm;

const int N = 1e5 + 7;
int n, k, degree[N], num[N], ans[N];
std::vector<pii> E[N];
std::vector<pii> G[N];
std::queue<int> Q;

int dfn[N], low[N], is_stack[N], t = 0, st[N], tp = 0, g[N], cnt = 0;

inline void tarjan(int now) {
	dfn[now] = low[now] = ++t;
    st[++tp] = now; is_stack[now] = 1;
	for(auto to : E[now]) {
		if(!dfn[to.fi]) {
			tarjan(to.fi);
            smin(low[now], low[to.fi]);
		}
		else if(is_stack[to.fi]) {
			smin(low[now], dfn[to.fi]);
		}
	}
	if(low[now] == dfn[now]) {
		++cnt;
		while(1) {
            is_stack[st[tp]] = 0;
			g[st[tp]] = now;
			if(low[st[tp]] == dfn[st[tp]]) {
				tp--;
				break;
			}
			num[now] += num[st[tp]];
			degree[now] += degree[st[tp]];
			tp--;
		}
	}
	return ;
}

signed main() {

	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);

	read(n, k);
	for (int i = 1; i <= n; ++i) 
		num[i] = 1;
	
	for (int i = 1; i <= k; ++i) {
		int x;
		read(x);
		switch(x) {
			case 1: {
				int u, v;
				read(u, v);
				E[u].push_back({v, 0});
				E[v].push_back({u, 0});
				break;
			}
			case 2: {
				int u, v;
				read(u, v);
				E[u].push_back({v, 1});
				break;
			}
			case 3: {
				int u, v;
				read(u, v);
				E[u].push_back({v, 0});
				break;
			}
			case 4: {
				int u, v;
                read(u, v);
                E[v].push_back({u, 1});
                break;
			}
			case 5: {
				int u, v;
				read(u, v);
				E[v].push_back({u, 0});
				break;
			}
		}
	}

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

	for (int i = 1; i <= n; ++i) {
		for (auto it : E[i]) {
			if(it.se == 1 && g[i] == g[it.fi]) {
				write(-1);
				return 0;
			}
			if(g[i] != g[it.fi]) {
				G[g[i]].push_back({g[it.fi], it.se});
				degree[g[it.fi]]++;
			}
		}
	}

	for (int i = 1; i <= cnt; ++i) {
		if(!degree[i])
			Q.push(i), ans[i] = 1;
	}

	while(!Q.empty()) {
		int front = Q.front();
		Q.pop();
		for (auto it : G[front]) {
			ans[it.fi] = ans[front] + it.se;
			degree[it.fi]--;
			if(!degree[it.fi]) {
				Q.push(it.fi);
			}
		}
	}

	
	ll ANS = 0;
	for (int i = 1; i <= cnt; ++i) {
		ANS += 1ll * ans[i] * num[i];
	}
	write(ANS);

	return 0;
}

回复

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

正在加载回复...