LuoguP3183 [HAOI2016]食物链 记忆化搜索
题目描述
如图所示为某生态系统的食物网示意图,据图回答第1小题现在给你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 <bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f #define il inline #define in1(a) a=read() #define in2(a,b) in1(a),in1(b) #define in3(a,b,c) in2(a,b),in1(c) #define in4(a,b,c,d) in2(a,b),in2(c,d) #define out(a) printf( "%d" , a ) #define outn(a) out(a),putchar('\n') #define I_int int inline I_int read() { I_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 << 1) + (x << 3) + c - 48 ; c = getchar() ; } return x * f ; } #undef I_int using namespace std ; #define N 100010 int n , m ; int in[ N ] , out[ N ] ; int head[ N ] , cnt ; struct node { int to , nxt ; } e[ N << 1 ] ; void ins( int u , int v ) { e[ ++ cnt ].to = v ; e[ cnt ].nxt = head[ u ] ; head[ u ] = cnt ; } int f[ N ] ; int dfs( int x ) { if( f[ x ] ) return f[ x ] ; int ans = 0 ; if( !out[ x ] && in[ x ] ) ans ++ ; for( int i = head[ x ] ; i ; i = e[ i ].nxt ) { ans += dfs( e[ i ].to ) ; } f[ x ] = ans ; return ans ; } int main() { in2( n , m ) ; for( int i = 1 , u , v ; i <= m ; i ++ ) { in2( u , v ) ; ins( u , v ) ; in[ v ] ++ ; out[ u ] ++ ; } int ans = 0 ; for( int i = 1 ; i <= n ; i ++ ) { if( !in[ i ] ) ans += dfs( i ) ; } outn( ans ) ; }