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

4562: [Haoi2016]食物链

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

Description

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

Input

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

Output

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

Sample Input

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

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]);
    }
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值