Oudasheng 2020-06-13
https://www.luogu.com.cn/problem/P4017

题目的意思是从入度为0的起点开始,到出度为0的终点结束,统计这样的路径一共有多少条
这样就涉及到了拓扑排序的概念
没有前驱的顶点输出。(可以遍历,也可以用优先队列维护)删除以这个点为起点的边。(它的指向的边删除,为了找到下个没有前驱的顶点)由于图中存在的起点(入度为零的点)可能不止一个,那个这个路径寻找的过程要执行多次,所以要先把这样的起点入队
然后执行拓扑排序的寻找方法,一旦入队变为零就将该节点入队
由于图中出度为零的点也不止一个,所以将图中所有出度为0的节点的拓扑路径书相加就是答案
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
int dp[5002];
vector<int>edges[5003];
int in[5003], out[5003];
int n, m;
queue<int>list;
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++)
{
int a, b;
scanf("%d%d", &a, &b);
//edges[a][b] = 1;
edges[a].push_back(b);
in[b]++;
out[a]++;
}
for (int i = 1; i <=n; i++)
{
if (in[i] == 0)
{
list.push(i);
dp[i] = 1;
}
}
while (!list.empty())
{
int temp = list.front(); list.pop();
for (int i =0; i <edges[temp].size(); i++)
{
in[edges[temp][i]]--;
if (in[edges[temp][i]] == 0)list.push(edges[temp][i]);
dp[edges[temp][i]] =( dp[temp] + dp[edges[temp][i]])%80112002;
}
}
int sum = 0;
for (int i = 1; i <=n; i++)
{
if (out[i] == 0)
sum = (sum + dp[i]) % 80112002;
}
printf("%d", sum);
}注意拓扑排序的习题中队列的使用