题意:给出有向边,并且有向边可以传递,即A可以到B,B可以到C,则A可以到C
问有多少节点可以由其它除其本身的所有节点到达;
强联通转化:强联通缩点后,若出度为零的点不唯一,则无解,若唯一,求联通块的节点数,,,
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<map>
#include<cmath>
#include<iostream>
#include <queue>
//#include <stack>
#include<algorithm>
#include<set>
using namespace std;
#define INF 1e8
#define eps 1e-8
#define LL __int64
#define maxn 26
#define mol 1000000007
#define N 10010
#define M 50010
struct Edge
{
int v;
int next;
};
Edge edge[M];//边的集合
int node[N];//顶点集合
int instack[N];//标记是否在stack中
int stack[N];
int Belong[N];//各顶点属于哪个强连通分量
int DFN[N];//节点u搜索的序号(时间戳)
int LOW[N];//u或u的子树能够追溯到的最早的栈中节点的序号(时间戳)
int n, m;//n:点的个数;m:边的条数
int cnt_edge;//边的计数器
int Index;//序号(时间戳)
int top;
int Bcnt;//有多少个强连通分量
int in[N],out[N],numd[N];
void add_edge(int u, int v)//邻接表存储
{
edge[cnt_edge].next = node[u];
edge[cnt_edge].v = v;
node[u] = cnt_edge++;
}
void tarjan(int u)
{
int i, j;
int v;
DFN[u] = LOW[u] = ++Index;
instack[u] = true;
stack[++top] = u;
for (i = node[u]; i != -1; i = edge[i].next)
{
v = edge[i].v;
if (!DFN[v])//如果点v没被访问//树枝边
{
tarjan(v);
if (LOW[v]<LOW[u])
LOW[u] = LOW[v];
}
else//如果点v已经被访问过//后向边
if (instack[v] && DFN[v]<LOW[u])
LOW[u] = DFN[v];
}
if (DFN[u] == LOW[u])//缩点
{
Bcnt++;
do
{
j = stack[top--];
instack[j] = false;
Belong[j] = Bcnt;
} while (j != u);
}
}
void solve()
{
int i;
top = Bcnt = Index = 0;
memset(DFN, 0, sizeof(DFN));
memset(LOW, 0, sizeof(LOW));
memset(Belong, 0, sizeof(Belong));
for (i = 1; i <= n; i++)
if (!DFN[i])
tarjan(i);
}
int main()
{
//freopen("in.txt", "r", stdin);
int i, j, k, t;
while(~scanf("%d %d", &n,&m))
{
cnt_edge = 0;
memset(node, -1, sizeof(node));
for (i = 1; i <= m; i++)
{
scanf("%d%d", &j,&k);
add_edge(j,k);
}
solve();
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(numd,0,sizeof(numd));
for(i=1;i<=n;i++)
{
for(j=node[i];j!=-1;j=edge[j].next )
{
if(Belong[i]!=Belong[edge[j].v])
{
in[Belong[edge[j].v]]++;
out[Belong[i]]++;
}
}
}
int a,b=0;
for(i=1;i<=Bcnt;i++)
{
if(!out[i])
{
b++;
a=i;
}
}
if(b!=1) printf("0\n");
else
{
int ans=0;
for(i=1;i<=n;i++)
{
if(Belong[i]==a)
ans++;
}
printf("%d\n",ans);
}
}
return 0;
}
/*
3 3
1 2
2 1
2 3
*/