Lors du tri topologique, définissez le chef d'équipe actuel sur u et pour u-> v, définissez la vis du nœud v visité sur u, afin que vous puissiez juger si ce bord est en double
例: JO 1566
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; inline long long read () { long long ans = 0 , f = 1 ; char ch = getchar (); tandis que (! isdigit (ch)) f * = (ch == ' - ' )? - 1 : 1 , ch = getchar (); faire ans = (ans << 1) + (ans << 3 ) + (ch ^ 48 ), ch = getchar (); while (isdigit (ch)); return ans * f; } const int MAXN = 100005 , MAXM = 1000005 ; struct Graph { int head [MAXN], last [MAXM], next [MAXM], lineNum; void add ( int x, int y) { lineNum ++, next [lineNum] = head [x], last [lineNum] = y, head [x] = lineNum; } } G, G2; intdfn [MAXN], bas [MAXN], vis [MAXN], taille [MAXN], bel [MAXN], sta [MAXN], pouce [MAXN], cnt = 0 ; int Dp [MAXN], dep [MAXN]; file d'attente < int > Q; void tarjan ( int x) { dfn [x] = low [x] = ++ dfn [ 0 ], sta [++ sta [ 0 ]] = x, vis [x] = true ; pour ( int l = G.head [x]; l; l = G.next [l]) { int y = G.last [l]; if (! dfn [y]) tarjan (y), low [x] = min (low [x], low [y]); sinon si (vis [y]) faible [x] =min (faible [x], dfn [y]); } if (low [x] == dfn [x]) { cnt ++ ; do bel [sta [sta [ 0 ]]] = cnt, vis [sta [sta [ 0 ]]] = false , siz [cnt] ++ ; while (sta [sta [ 0 ] -]! = x); } } int main () { int N = read (), M = read (), MOD = read (); pour ( int i = 1 ; i <= M; i ++ ) { int u = read (), v = read (); G.add (u, v); } pour ( int i = 1 ; i <= N; i ++) if (! dfn [i]) tarjan (i); pour ( int x = 1 ; x <= N; x ++) pour ( int l = G.head [x]; l; l = G.next [l]) { int y = G.last [l]; if (bel [x]! = bel [y]) G2.add (bel [x], bel [y]), inch [bel [y]] ++ ; } for ( int i = 1 ; i <= cnt; i ++) if (! inch [i]) Q.push (i), dep [i]= siz [i], Dp [i] = 1 ; memset (vis, 0 , sizeof (vis)); while (! Q.empty ()) { int x = Q.front (); Q.pop (); pour ( int l = G2.head [x]; l; l = G2.next [l]) { int y = G2.last [l]; pouce [y] - ; if (! inch [y]) Q.push (y); si (vis [y] == x) continue ; vis [y] = x; if (dep [y] <dep [x] + siz [y]) dep [y] = dep [x] + siz [y], Dp [y] = Dp [x]; sinon si (dep [y] == dep [x] + siz [y]) Dp [y] = (Dp [y] + Dp [x])% MOD; } } int ans = 0 , maxDep = 0 ; for ( int i = 1 ; i <= cnt; i ++ ) { if (maxDep < dep [i]) maxDep = dep [i], ans = Dp [i]; sinon if (maxDep == dep [i]) ans = (ans + Dp [i])% MOD; } printf ( " % d \ n% d " , maxDep, ans); retourner 0 ; }