tarjan + 拓扑序板子题
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x ; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
typedef long long ll;
using namespace std;
template<typename T>inline void read(T&x)
{
char c;int sign = 1;x = 0;
do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c = getchar();}while(isdigit(c));
x *= sign;
}
const int N = 2e6 + 20;
int head[N],nxt[N],to[N],tot;
int Head[N],Nxt[N],To[N],Tot;
inline void add(int x,int y)
{
to[tot] = y;
nxt[tot] = head[x];
head[x] = tot++;
}
inline void Add(int x,int y)
{
To[Tot] = y;
Nxt[Tot] = Head[x];
Head[x] = Tot++;
}
int n,m,p;
int size[N],dfn[N],low[N],belong[N],cnt,sz;
int s[N],top; bool inq[N];
void tarjan(int x)
{
dfn[x] = low[x] = ++sz;
s[++top] = x; inq[x] = 1;
for(register int i = head[x];~i;i=nxt[i])
if(!dfn[to[i]])
{
tarjan(to[i]);
low[x] = min(low[x],low[to[i]]);
}else if(inq[to[i]]) low[x] = min(low[x],dfn[to[i]]);
if(dfn[x] == low[x])
{
belong[x] = ++cnt; inq[x] = 0;++ size[cnt];
while(s[top] != x)
{
++size[cnt];
belong[s[top]] = cnt;
inq[s[top--]] = 0;
}
--top;
}
}
int in[N];
ll f[N],g[N],num,ans;
inline void rebuild()
{
rep(x,1,n)
{
for(register int i = head[x];~i;i=nxt[i])
if(belong[to[i]] != belong[x])
Add(belong[x],belong[to[i]]),
++in[belong[to[i]]];
}
rep(i,1,cnt) g[i] = size[i],f[i] = 1;
}
int vis[N],now;
int q[N],st,en;
inline void toposort()
{
st = 1;
rep(i,1,cnt) if(!in[i]) q[++en] = i;
while(st <= en)
{
int x = q[st++]; ++ now;
if(g[x] > ans) ans = g[x],num = f[x];
else if(g[x] == ans) num = (num + f[x]) % p;
for(register int i = Head[x];~i;i=Nxt[i])
{
int t = To[i]; -- in[t];
if(!in[t]) q[++en] = t;
if(vis[t] == now) continue; vis[t] = now;
if(g[x] + size[t] > g[t]) g[t] = g[x] + size[t],f[t] = f[x];
else if(g[x] + size[t] == g[t])
f[t] = (f[t] + f[x]) % p;
}
}
}
int main()
{
memset(head,-1,sizeof head);
memset(Head,-1,sizeof Head);
read(n); read(m); read(p);
rep(i,1,m)
{
int u,v;
read(u); read(v);
add(u,v);
}
rep(i,1,n) if(!dfn[i]) tarjan(i);
rebuild();
toposort();
cout << ans << endl << num << endl;
return 0;
}