题目链接:https://www.luogu.com.cn/problem/P4017
这一题考察拓扑图,是一道板子题。
这里介绍用图存储信息和用链表存储信息两种方法
首先是用图存储吃与被吃的关系
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 5010, M = 500010, mod = 80112002;
int n, m;
int r[N], c[N];
int mp[N][N], f[N];
int ans;
queue<int> q;
int main(){
cin >> n >> m;
while(m -- ){
int a, b; scanf("%d%d", &a, &b);
r[b] ++, c[a] ++;
mp[a][b] = 1;
}
for (int i = 1; i <= n; i ++ ){
if (!r[i]) f[i] = 1, q.push(i);
}
while (q.size()){
int t = q.front();
q.pop();
for (int i = 1; i <= n; i ++ ){
if (!mp[t][i]) continue;
f[i] += f[t];
f[i] %= mod;
r[i] --;
if (!r[i]){
if (!c[i]){
ans += f[i];
ans %= mod;
continue;
}
q.push(i);
}
}
}
cout << ans << endl;
return 0;
}
这里介绍用数组模拟单链表的方法来存储吃与被吃的关系。
//拓扑图
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 5010, M = 500010, mod = 80112002;
int n, m;
int h[N], e[M], ne[M], idx;
int r[N], c[N], f[N];//入度与出度
int ans;
void add(int a, int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
}
void topsort(){
queue<int> q;
for (int i = 1; i <= n; i ++ )
if (!r[i]) {
q.push(i);
f[i] = 1;
}
while (q.size()){
int t = q.front();
q.pop();
for (int i = h[t]; i != -1; i = ne[i]){
int j = e[i];
r[j] --; f[j] += f[t];
f[j] %= mod;
if (!r[j]){
if (!c[j]) {
ans += f[j];
ans %= mod;
}
else q.push(j);
}
}
}
}
int main(){
cin >> n >> m;
memset(h, -1, sizeof h);
while (m -- ){
int a, b; scanf("%d%d", &a, & b);
add(a, b);
r[b] ++;
c[a] ++;
}
topsort();
cout << ans << endl;
return 0;
}