来自洛谷P4017 最大食物链计数
解题思路首先这道题先学会合理使用vector,因为这里食物链的表示其实类似于有向图的邻接表,而一般来说我们需要使用队列的结构,但是通过vector,可以很容易得就模拟出队列的状态,并且可以通过下标来访问!
在这里我们只需要记录下所有的非被捕食者,然后采取DFS记忆化搜索的方式即可
要注意mod
另外还需要注意下标,因为读入的下标的是从1开始的!!
代码实现#define _CRT_SECURE_NO_WARNINGS #include附加部分using namespace std; #define rep(i,s,n) for(int i=s;i Eat[SIZE]; bool HEat[SIZE]; int res[SIZE]; int dfs(int i) { int ans = 0; if (Eat[i].size() < 1) return res[i] = 1; if (res[i] != 0) return res[i]; rep(j, 0, Eat[i].size()) { int &temp = Eat[i][j]; ans+= res[temp] ? res[temp] : dfs(temp); ans %=mod; } return res[i] = ans; } int main() { int n,m; scanf("%d %d", &n, &m); memset(res, 0, sizeof(res)); memset(HEat, 0, sizeof(HEat)); rep(i, 0, m) { int x, y; scanf("%d %d", &x, &y); Eat[y].push_back(x); HEat[x] = true;//x是被捕食者 } int ans = 0; rep(i, 1, n+1) { if (!HEat[i]) ans = (ans + dfs(i)) % mod; } printf("%d", ans); return 0; }
另外这道题还可以采取拓扑排序的方式
记录下所有入度为0的点,然后依次向后查找,直到找到出度为0的点
#include注意using namespace std; int n, m, ru[5005], chu[5005], a, b, f[5005], ans; int mp[5005][5005]; queue q; const int mod =80112002; int main() { cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> a >> b; mp[b][a] = 1;//记录关系 ru[a]++; chu[b]++;//记录入度和出度 } for (int i = 1; i <= n; i++) { if (ru[i] == 0) { f[i] = 1; q.push(i); } } while (!q.empty()) { int a = q.front(); q.pop(); for (int i = 1; i <= n; i++) { if (mp[a][i] == 0) continue; f[i] += f[a]; f[i] %= mod; ru[i]--; if (ru[i] == 0) { if (chu[i] == 0) { ans += f[i]; ans %= mod; continue; } q.push(i); } } } cout << ans; return 0; }
比较关键的点在于对f[i]的初始化! 以及入度要减1!!!



