社区讨论
可爱萌新不会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 条回复,欢迎继续交流。
正在加载回复...