挺显然的吧,一条边没有影响当且仅当这个边相连的两个点已经可以互相到达,就是没想到用bitset维护,老纠结map。。。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<bitset>
#include<queue>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=3e4+5;
int n,m;
bitset<N> f[N];
queue<int>q;
int d[N],a[N],tot;
int head[100005],go[100005],next[100005];
inline void add(int x,int y)
{
go[++tot]=y;
next[tot]=head[x];
head[x]=tot;
}
inline void topsort()
{
int a1=0;
fo(i,1,n)if (!d[i])q.push(i);
while (!q.empty())
{
int x=q.front();
q.pop();
a[++a1]=x;
for(int i=head[x];i;i=next[i])
{
int v=go[i];
d[v]--;
if (!d[v])q.push(v);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
fo(i,1,m)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
d[y]++;
}
topsort();
int ans=0;
fd(i,n,1)
{
int x=a[i];
for(int j=head[x];j;j=next[j])
{
int v=go[j];
f[x]|=f[v];
}
for(int j=head[x];j;j=next[j])
{
int v=go[j];
if (f[x][v])ans++;
f[x].set(v);
}
}
printf("%d\n",ans);
}