2266. [HAOI2016]食物链 记忆化

2266. [HAOI2016]食物链

★   输入文件:chain_2016.in   输出文件:chain_2016.out   简单对比
时间限制:1 s   内存限制:128 MB

【题目描述】

如图所示为某生态系统的食物网示意图,据图回答第一小题。

1.数一数,在这个食物网中有几条食物链(   )

现在给你n个物种和m条能量流动关系,求其中的食物链条数。

物种的名称为从1n编号,m条能量流动关系形如

a1 b1

a2 b2

a3 b3

am1 bm1

am bm

其中ai bi表示能量从物种ai流向物种bi

【输入格式】

第一行两个正整数nm

接下来m行每行两个整数ai bi表示m条能量流动关系。

(数据保证输入数据符合生物学特点,且不会有重复的能量流动关系出现)

【输出格式】

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

【样例输入】

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

【样例输出】

9

【样例解释】

就是上面题目描述1的那个图。

各个物种的编号依次为:

草<->1 兔<->2 狐<->3 鼠<->4 猫头鹰<->5 吃虫的鸟<->6 蜘蛛<->7 蛇<->8 青蛙<->9 食草昆虫<->10。

【数据范围】

1n100000,0m200000

【来源】

HAOI2016上午第一题 部分题面由ck进行调整

//单点不算食物链
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>

using namespace std;
const int N=200010;

int U[N>>1],V[N>>1],V0[N>>1];
int head[N>>1];
int ans[N>>1];
bool vis[N>>1];
int now=1;
int n,m,js;
int answer;
struct node{
    int u,v,nxt;
}E[N];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    return x*f;
}

inline void add(int u,int v)
{
    E[now].u=u;
    E[now].v=v;
    E[now].nxt=head[u];
    head[u]=now++;
}

void dfs(int start)
{
    vis[start]=1;
    if(!U[start])
    {
        answer++;
        return ;
    }
    for(int i=head[start];~i;i=E[i].nxt)
        if(!vis[E[i].v])
            dfs(E[i].v),
            vis[E[i].v]=0;
}

int main()
{
    freopen("chain_2016.in","r",stdin);
    freopen("chain_2016.out","w",stdout);
    n=read();
    m=read();
    for(int i=1;i<=n;i++)
        head[i]=-1;
    for(int i=1;i<=m;i++)
    {
        int u=read(),v=read();
        U[u]++,V[v]++;
        add(u,v);
    }
    for(int i=1;i<=n;i++)
        if(!V[i]&&U[i])
            V0[++js]=i;
    for(int i=1;i<=js;i++)
        dfs(V0[i]);
    printf("%d",answer);        
    
    return 0;
}
/*
10 16
1 2
1 4
1 10
2 3
2 5
4 3
4 5
4 8
6 8
7 6
7 9
8 5
9 8
10 6
10 7
10 9
*/

 记忆化搜索:

//单点不算食物链
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>

using namespace std;
const int N=200010;

int U[N>>1],V[N>>1],V0[N>>1];
int head[N>>1];
int ans[N>>1];
bool vis[N>>1];
int now=1;
int n,m,js;
int answer;
struct node{
    int u,v,nxt;
}E[N];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    return x*f;
}

inline void add(int u,int v)
{
    E[now].u=u;
    E[now].v=v;
    E[now].nxt=head[u];
    head[u]=now++;
}

int dfs(int start)
{
    if(!U[start])
        ans[start]++;
    for(int i=head[start];~i;i=E[i].nxt)
        if(ans[E[i].v])
            ans[start]+=ans[E[i].v];
        else
            ans[start]+=dfs(E[i].v);
    return ans[start];
}

int main()
{
    freopen("chain_2016.in","r",stdin);
    freopen("chain_2016.out","w",stdout);
    n=read();
    m=read();
    for(int i=1;i<=n;i++)
        head[i]=-1;
    for(int i=1;i<=m;i++)
    {
        int u=read(),v=read();
        U[u]++,V[v]++;
        add(u,v);
    }
    for(int i=1;i<=n;i++)
        if(!V[i]&&U[i])
            V0[++js]=i;
    for(int i=1;i<=js;i++)
        answer+=dfs(V0[i]);
        
    printf("%d",answer);        
    
    return 0;
}

 

posted @ 2017-07-05 15:27  ioioioioioio  阅读(199)  评论(0编辑  收藏  举报