rt,这题从缩点题解过来的,一看拓扑能做就写了。 写完了之后调半天92pts,啥错都看不出来了。。。
然后看题解换成了题解的非拓扑做法ac了
(推测是拓扑写挂了)
#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>
#include <map>
#define maxn 10010
#define maxm 50010
#define ll long long
using namespace std;
ll n,m;
struct fw
{
ll next,to;
}a[maxm],f[maxm];
ll head[maxn],dfn[maxn],low[maxn],vis[maxn],cnt,scc,dis[maxn],id[maxn],x[maxm],y[maxm],rd[maxn];
stack <ll> p;
queue <ll> q;
map <ll,map<ll,ll> > mp;
void dfs(ll k)
{
dfn[k]=low[k]=++cnt;
vis[k]=1;
p.push(k);
for(int i=head[k];i;i=a[i].next)
{
ll v=a[i].to;
if(!dfn[v]) dfs(v);
if(vis[v]) low[k]=min(low[k],low[v]);
}
if(low[k]==dfn[k])
{
++scc;
ll sum=0;
while(1)
{
ll u=p.top();
p.pop();
vis[u]=0;
id[u]=scc;
sum++;
if(u==k) break;
}
dis[scc]=sum;
}
}
void topu()
{
for(int i=1;i<=scc;i++) if(rd[i]==0) q.push(i);
while(!q.empty())
{
ll u=q.front();
q.pop();
for(int i=head[u];i;i=f[i].next)
{
ll v=f[i].to;
dis[v]+=dis[u];
rd[v]--;
if(rd[v]==0) q.push(v);
}
}
ll ans=0;
for(int i=1;i<=n;i++) if(dis[id[i]]==n) ans++;
cout<<ans<<"\n";
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>x[i]>>y[i];
a[++cnt].next=head[x[i]];
a[cnt].to=y[i];
head[x[i]]=cnt;
}
cnt=0;
for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);
cnt=0;
for(int i=1;i<=n;i++) head[i]=0;
for(int i=1;i<=m;i++)
{
ll u=id[x[i]],v=id[y[i]];
if(u!=v&&!mp[u][v])
{
mp[u][v]=1;
rd[v]++;
f[++cnt].next=head[u];
f[cnt].to=v;
head[u]=cnt;
}
}
topu();
return 0;
}