2266. [HAOI2016]食物链 记忆化
2266. [HAOI2016]食物链
★ 输入文件:chain_2016.in
输出文件:chain_2016.out
简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
如图所示为某生态系统的食物网示意图,据图回答第一小题。
1.数一数,在这个食物网中有几条食物链( )
现在给你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 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。
【数据范围】
1≤n≤100000,0≤m≤200000。
【来源】
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; }