玄关:MnZn 奶大龙刚学 OI 阳历美国 50pts 求条
查看原帖
玄关:MnZn 奶大龙刚学 OI 阳历美国 50pts 求条
1378591
Barewalk楼主2025/2/3 19:44

rt

#include <iostream>
#define maxN 100100
#define maxM 200200
using namespace std;
int n, m;
int head[maxN][2], edge[maxM][2], nxt[maxM][2], to[maxM][2], cnt;
void addEdge(int x, int y, int z, bool f) {
    nxt[++ cnt][f] = head[x][f];
    to[head[x][f] = cnt][f] = y;
    edge[cnt][f] = z;
}
bool vis[maxN];
int anc[maxN], top;
int dfn[maxN], low[maxN], idx;
int scc[maxN], size[maxN], tot;
void tarjan(int x) {
    low[x] = dfn[x] = ++ idx;
    anc[++ top] = x, vis[x] = true;
    for (int i = head[x][0]; i; i = nxt[i][0]) {
        int y = to[i][0];
        if (!dfn[y]) {
            tarjan(y);
            low[x] = min(low[x], low[y]);
        } else if (vis[y]) {
            low[x] = min(low[x], dfn[y]);
        }
    }
    if (dfn[x] == low[x]) {
        int y = 0; tot ++;
        while (x ^ y) {
            y = anc[top --], vis[y] = false, scc[y] = tot, size[tot] ++;
        }
    }
}
int q[maxN], st = 1, ed;
int candy[maxN], inDegree[maxN], ans;
int topSort() {
    for (int i = 1; i <= tot; ++ i) {
        if (!inDegree[i]) q[++ ed] = i;
        candy[i] = 1;
    }
    while (st <= ed) {
        int x = q[st ++];
        for (int i = head[x][1]; i; i = nxt[i][1]) {
            int y = nxt[i][1];
            candy[y] = max(candy[y], candy[x] + edge[i][1]);
            if (-- inDegree[y] == 0) q[++ ed] = y;
        }
    }
    for (int i = 1; i <= tot; ++ i) ans += candy[i] * size[i];
    return ans;
}
int main() {
    cin >> n >> m;
    for (int i = 1; i <= m; ++ i) {
        int x, a, b; cin >> x >> a >> b;
        if (x == 1) addEdge(a, b, 0, 0), addEdge(b, a, 0, 0);
        if (x == 2) addEdge(a, b, 1, 0);
        if (x == 3) addEdge(b, a, 0, 0);
        if (x == 4) addEdge(b, a, 1, 0);
        if (x == 5) addEdge(a, b, 0, 0);
    }
    for (int i = 1; i <= n; ++ i)
        if (!dfn[i]) tarjan(i);
    cnt = 0;
    for (int x = 1; x <= n; ++ x)
        for (int i = head[x][0]; i; i =nxt[i][0]) {
            int y = to[i][0], xx = scc[x], yy = scc[y];
            if (xx ^ yy) {
                addEdge(xx, yy, edge[i][0], 1), inDegree[yy] ++;
            } else if (edge[i][0]) {
                return puts("-1"), 0;
            }
        }
    cout << topSort() << '\n';
    return 0;
}
2025/2/3 19:44
加载中...