强连通分量,缩点
求出每个强连通分量,缩点,统计入度为零的点。
好像能用并查集加floyd?
学不来
#include#include #include #include #include using namespace std;int from[1000010],to[1000010],nex[1000010],head[10010],es;int instack[10010],dfn[10010],low[10010],belong[10010],dfsnum,sccnum;int sccenter[10010],sccout[10010];stack s;void tarjan(int u){ dfn[u]=low[u]=++dfsnum; instack[u]=true; s.push(u); for(int i=head[u];i;i=nex[i]) { if(!dfn[to[i]]) { tarjan(to[i]); low[u]=min(low[u],low[to[i]]); } else if(instack[to[i]]) low[u]=min(low[u],dfn[to[i]]); } if(dfn[u]==low[u]) { int v; ++sccnum; do { v=s.top(); s.pop(); belong[v]=sccnum; instack[v]=false; }while(u!=v); } return ;}int main(){ ios::sync_with_stdio(false); int n,m; cin>>n; for(int i=1;i<=n;i++) { cin>>m; while(m!=0) { from[++es]=i; to[es]=m; nex[es]=head[i]; head[i]=es; cin>>m; } } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=es;i++) { if(belong[from[i]]!=belong[to[i]]) { ++sccout[belong[from[i]]]; ++sccenter[belong[to[i]]]; } else continue; } int out=0,enter=0; for(int i=1;i<=sccnum;i++) { if(sccout[i]==0) ++out; if(sccenter[i]==0) ++enter; } cout<