[HAOI2016]食物链 (记忆化搜索)

来源:互联网 发布:skype for mac 编辑:程序博客网 时间:2024/05/22 03:22

题目描述

现在给你n个物种和m条能量流动关系,求其中的食物链条数。
物种的名称为从1到n编号M条能量流动关系形如a1 b1a2 b2a3 b3……am-1 bm-1am bm
其中ai bi表示能量从物种ai流向物种bi,注意单独的一种孤立生物不算一条食物链

输入输出格式

输入格式:

第一行两个整数n和m,接下来m行每行两个整数ai bi描述m条能量流动关系。(数据保证输入数据符号生物学特点,且不会有重复的能量流动关系出现)1<=N<=100000 0<=m<=200000题目保证答案不会爆 int

输出格式:

一个整数即食物网中的食物链条数

输入输出样例

输入样例#1:

10 16
1 2
1 4
1 10
2 3
2 5
4 3
4 5
4 8
6 5
7 6
7 9
8 5
9 8
10 6
10 7
10 9

输出样例#1:

9

思路

还是看入度出度的关系决定了一条食物链的起始,对结果记忆化搜索,

并且注意一个生物不算食物链(即单独的非连通点无效)

#include<cstdio>#include<iostream>#define maxn 100005#define maxm 200005using namespace std;int n,m,t,ans;int fa[maxn],head[maxn],son[maxn],v[maxn];struct node{    int from,to,next;}e[maxm];void add(int x,int y){    e[++t].from=x;    e[t].to=y;    e[t].next=head[x];    head[x]=t;}int read(){    int sum=0,f=1;    char ch=getchar();    while(ch<'0'||ch>'9')    {        if(ch=='-') f=-f;        ch=getchar();    }    while(ch>='0'&&ch<='9')    {        sum=sum*10+ch-'0';        ch=getchar();    }    return sum*f;}int dfs(int x){    if (v[x]) return v[x];//记忆化    int ans=0;    if (fa[x]==0) return 1;    for (int i=head[x];i;i=e[i].next)    {        ans+=dfs(e[i].to);    }    v[x]=ans;             //记忆化    return ans;}int main(){    n=read(),m=read();    int start;    for(int i=1;i<=m;i++)    {        int x=read(),y=read();        add(x,y);        fa[x]++; son[y]++;    }    for(int i=1;i<=n;i++)     if(son[i]==0&&fa[i]!=0)      {         ans+=dfs(i);        }    printf("%d",ans);    return 0;}
原创粉丝点击