首页 > 学院 > 开发设计 > 正文

BZOJ 4562 食物链【记忆化搜索啊】

2019-11-14 12:43:45
字体:
来源:转载
供稿:网友

4562: [Haoi2016]食物链

Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 352  Solved: 263[Submit][Status][Discuss]

Description

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

Input

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

Output

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

Sample Input

10 161 21 41 102 32 54 34 54 86 57 67 98 59 810 610 710 9

Sample Output

9

思路:

1、一开始在网上还找到了一个公式:食物链条数=分叉边数-分叉点数+1....

尼玛大骗纸不好用啊、分叉到两个子树中就尼玛不是一个东西了好伐。

2、统计计数问题考虑dp,设定dp【i】表示以i为根的子树食物链的条数。

那这个题就是水题啊,dp【i】=Σdp【v】;

然后设定个超级源点连度为0的所有节点,那么dp【0】就是答案啊。

3、注意孤立节点不算答案啊。就没了啊。

Ac代码:

#include<stdio.h>#include<string.h>#include<vector>using namespace std;vector<int >mp[100600];int degree[100600];int dp[100600];int n,m;int Dfs_Dp(int u){    if(dp[u]==-1)    {        dp[u]=0;        int size=mp[u].size();        for(int i=0;i<size;i++)        {            int v=mp[u][i];            dp[u]+=Dfs_Dp(v);        }        if(size==0)dp[u]=1;        return dp[u];    }    else return dp[u];}int main(){    while(~scanf("%d%d",&n,&m))    {        memset(dp,-1,sizeof(dp));        memset(degree,0,sizeof(degree));        for(int i=0;i<=n;i++)mp[i].clear();        for(int i=0;i<m;i++)        {            int x,y;            scanf("%d%d",&x,&y);            mp[x].push_back(y);            degree[y]++;        }        for(int i=1;i<=n;i++)        {            if(degree[i]==0&&mp[i].size()>0)mp[0].push_back(i);        }        if(mp[0].size()>0)        Dfs_Dp(0);        if(dp[0]<0)dp[0]=0;        PRintf("%d/n",dp[0]);    }}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表