1353-食物链
题目描述:
现在给你n个物种和m条能量流动关系,求其中的食物链条数。
物种的名称为从1到n的编号。
m 条能量流动关系形如
a1 b1
a2 b2
a3 b3
… …
am−1 bm−1
am bm
其中 ai bi表示能量从物种ai流向物种bi。
注意单独的一种孤立生物不算一条食物链。
输入描述:
多组数据每组第一行两个整数n和m,接下来m行每行两个整数ai bi描述m条能量流动关系。(保证输入数据符合生物学特点,且不会有重复的能量流动关系出现)
输出描述:
每组一个整数一行,即食物网中的食物链条数。
样例输入:
复制
10 161 21 41 102 32 54 34 54 86 57 67 98 59 810 610 710 9
样例输出:
9
提示:
1≤N≤100000,0≤m≤200000
保证答案不会超过 int 的最大值
思路:用Vis[x] 记录搜索过后得到的以x为起点时有多少条食物链。然后不断搜和用邻接表表示线;
#include <cstdio>
#include <cstring>
using namespace std;
const int MN = 200005;
int n, m, head[MN], vis[MN], size, U[MN], V[MN];
struct Edge
{
int v, next;
}E[MN];
void init()
{
memset(vis,0,sizeof(vis));
memset(U,0,sizeof(U));
memset(V,0,sizeof(V));
memset(head,-1,sizeof(head));
size = 0;
}
void add(int u,int v)
{
E[size].v = v, E[size].next = head[u];
head[u] = size++;
}
int dfs(int x)
{
if (vis[x]) return vis[x];//如果记录过直接调用
if (!U[x]) return 1;//到最高级一次,一条线;
int ans = 0;
for (int i = head[x];~i;i = E[i].next)
{
ans += dfs(E[i].v);
}
vis[x] = ans;//记录从x到最高级消费者的线数;
return ans;
}
int main()
{
int i, j, u, v;
while (~scanf("%d%d",&n,&m))
{
init();
for (i = 1;i <= m;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
U[u]++,V[v]++;
}
int ans = 0;
for (i = 1;i <= n;i++)
{
if(U[i] && V[i] == 0)
{
ans+=dfs(i);
}
}
printf("%d\n",ans);
}
return 0;
}