边化点+建正反图+记忆化搜索.
AC code:
#include <cstdio>
#include <vector>
using namespace std;
const int N=60010;
int n,m,ans;
int f1[N],f2[N];
vector<int> G1[N];
vector<int> G2[N];
void DFS1(int x){
if(!G1[x].size()){
f1[x]=1;
return ;
}
for(int i=0;i<(int)G1[x].size();i++){
if(!f1[G1[x][i]]) DFS1(G1[x][i]);
f1[x]+=f1[G1[x][i]];
}
}
void DFS2(int x){
if(!G2[x].size()){
f2[x]=1;
return ;
}
for(int i=0;i<(int)G2[x].size();i++){
if(!f2[G2[x][i]]) DFS2(G2[x][i]);
f2[x]+=f2[G2[x][i]];
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
G1[a].push_back(n+i);
G1[n+i].push_back(b);
G2[b].push_back(n+i);
G2[n+i].push_back(a);
}
for(int i=1;i<n;i++) if(!G2[i].size()) DFS1(i);
DFS2(n);
for(int i=n+1;i<=n+m;i++) if(f1[i]*f2[i]>ans) ans=f1[i]*f2[i];
printf("%d\n",ans);
return 0;
}