比赛 |
4043级2023省选模拟赛2 |
评测结果 |
WAAAAAAWWW |
题目名称 |
糖果 |
最终得分 |
60 |
用户昵称 |
zxhhh |
运行时间 |
0.095 s |
代码语言 |
C++ |
内存使用 |
9.35 MiB |
提交时间 |
2023-03-22 20:28:10 |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
typedef long long ll;
int n, k;
int dfn[N], low[N], scc_idx[N], scc_cnt, dfs_t, scc_siz[N], d[N], m[N], instk[N];
int stk[N], ed;
int ver[N<<2], nxt[N<<2], hd1[N], hd2[N], opt[N<<2], eidx = 1;
struct edge {
int x, y, op;
bool friend operator < (const edge & a, const edge & b) {
if (a.x != b.x) return a.x < b.x;
if (a.y != b.y) return a.y < b.y;
return a.op < b.op;
}
bool friend operator != (const edge & a, const edge & b) {
return a.x != b.x || a.y != b.y || a.op != b.op;
}
}edges[N<<2];
void add (int x, int y, int op, int hd[]) {
ver[++eidx] = y;
opt[eidx] = op;
nxt[eidx] = hd[x];
hd[x] = eidx;
}
void tarjan (int x) {
dfn[x] = low[x] = ++dfs_t; stk[ed++] = x; instk[x] = 1;
for (int i = hd1[x]; i ;i = nxt[i]) {
int y = ver[i];
if (!dfn[y]) tarjan(y), low[x] = min(low[x], low[y]);
else if (instk[y]) low[x] = min(low[x], dfn[y]);
}
if (low[x] == dfn[x]) {
int tmp = -1; scc_cnt++;
do {
tmp = stk[--ed];
instk[tmp] = 0;
scc_idx[tmp] = scc_cnt;
scc_siz[scc_cnt]++;
} while (tmp != x);
}
}
ll merge () {
int ecnt = 0; ll ans = 0;
for (int i = 1;i <= n;i++) {
for (int j = hd1[i]; j ;j = nxt[j]) {
int y = ver[j];
if (scc_idx[y] == scc_idx[i] && !opt[j]) return -1;
int tx = scc_idx[i], ty = scc_idx[y];
if (tx != ty) edges[++ecnt] = (edge){tx, ty, opt[j]};
}
}
sort (edges+1, edges+1+ecnt);
eidx = 0;
queue <int> q;
for (int i = 1;i <= ecnt;i++) if (edges[i] != edges[i-1]) add(edges[i].x, edges[i].y, edges[i].op, hd2), d[edges[i].y]++;
for (int i = 1;i <= scc_cnt;i++) if (!d[i]) q.push(i), m[i] = 1;
while (q.size()) {
int t = q.front(); q.pop();
ans += (ll)m[t]*scc_siz[t];
for (int i = hd2[t]; i ;i = nxt[i]) {
int y = ver[i];
d[y]--;
if (opt[i]) m[y] = max(m[y], m[t]);
else m[y] = max(m[y], m[t]+1);
if (!d[y]) q.push(y);
}
}
return ans;
}
int main () {
freopen("tangguo.in", "r", stdin);
freopen("tangguo.out", "w", stdout);
scanf("%d%d", &n, &k);
while (k--) {
int x, a, b, op;
scanf("%d%d%d", &x, &a, &b);
if (x == 1) {
add(a, b, 1, hd1); add(b, a, 1, hd1);
continue;
}
if (x >= 4) swap(a, b);
op = x&1;
add(a, b, op, hd1);
}
for (int i = 1;i <= n;i++) if (!dfn[i]) tarjan(i);
printf("%lld\n", merge());
return 0;
}