当前位置: 首页 > article >正文

【16届蓝桥杯寒假刷题营】第2期DAY1I

4.有向无环的路径数 - 蓝桥云课

问题描述

给定 N 个节点 M 条边的有向无环图,请你求解有多少条 1 到 N 的路径。

由于答案可能很大,你只需要输出答案对 998244353 取模后的结果。

输入格式

第一行包含 2 个正整数 N,M,表示有向无环图的节点数和边数。

之后 M 行,每行给定 2 个正整数 u,v (ueqv 且 1≤u,v≤N),表示图中存在一条有向边 (u,v)。

输出格式

输出一行,包含一个整数,表示答案,答案对 998244353 取模后的结果。

样例输入

4 4
1 2
2 3
1 3
3 4

样例输出

2

评测数据规模

对于所有测评数据,1≤N,M≤1e5。

思路:

暴力搜
代码如下:
 

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,m,ans,tot;
const ll N = 1e5+10;
const ll mod = 998244353;
ll head[N];
struct Edge{
	ll next;
	ll to;
}e[N];
bool vis[N];
void add(ll u,ll v)
{
	tot++;
	e[tot].next = head[u];
	e[tot].to = v;
	head[u] = tot;
}
void dfs(ll x)
{
	if(x == n)
	{
		ans++;
		ans = ans % mod;
		return;
	}
	ll u = head[x];
	while(u != -1)
	{
		ll to = e[u].to;
		if(!vis[to])
		{
			vis[to] = true;
			dfs(to);
			vis[to] = false;	
		}
		u = e[u].next;
	}
}
int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	cin >> n >> m;
	for(ll i = 1 ; i <= n ; i++)
	head[i] = -1;
	for(ll i = 1 ; i <= m ; i++)
	{
		ll u,v;
		cin >> u >> v;
		add(u,v);
	}
	vis[1] = true;
	dfs(1);
	cout << ans;
	return 0;
 } 

思路:

拓扑排序和dp‘

代码如下:

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
ll n,m,ans,tot;
const ll N = 1e5+10;
const ll mod = 998244353;
ll head[N],rd[N],dis[N];
struct Edge{
	ll next;
	ll to;
}e[N];
bool vis[N];
void add(ll u,ll v)
{
	tot++;
	e[tot].next = head[u];
	e[tot].to = v;
	head[u] = tot;
}

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	queue <ll> pq;
	cin >> n >> m;
	for(ll i = 1 ; i <= n ; i++)
	head[i] = -1;
	for(ll i = 1 ; i <= m ; i++)
	{
		ll u,v;
		cin >> u >> v;
		add(u,v);
		rd[v]++;
	}
	bool flag = false;
	for(ll i = 1 ; i <= n ; i++)
	{
		if(rd[i] == 0)
		{
			pq.push(i);
			if(i == 1)
			{
				dis[i] = 1;
				flag = true;
			}
		}
	}
	while(!pq.empty())
	{
		ll pos = pq.front();
		pq.pop();
		if(pos == 1 && !flag)
		{
          dis[pos] = 1;
          flag = true;
        }
		ll u = head[pos];
		while(u != -1)
		{
			ll to = e[u].to;
			rd[to]--;
			dis[to] = (dis[to] + dis[pos])%mod; 
			if(rd[to] == 0)
			{
				pq.push(to);
			}
			u = e[u].next;
		}	 
	}
	cout << dis[n];
	return 0;
 } 


http://www.kler.cn/a/551267.html

相关文章:

  • 采用分布式部署deepseek
  • 【白话Spring】三级缓存
  • 【C语言】有序数组的平方
  • 面试真题 | 招银 C++
  • 阿里4面+腾讯4面春招面试题解析,附Java 岗 988 道题分享
  • SQL注入(SQL Injection)详解与实战
  • LVS 负载均衡集群(DR 模式)
  • ThreadLocal为什么会内存溢出
  • 【deepseek之我问】如何把AI技术与教育相结合,适龄教育,九年义务教育,以及大学教育,更着重英语学习。如何结合,给出观点。结合最新智能体Deepseek
  • 【Docker】ollama部署deepseek
  • HDFS是如何存储和管理大数据
  • 移动通信发展史
  • 【个人开发】deepspeed+Llama-factory 本地数据多卡Lora微调【完整教程】
  • mysql多主集群 galera cluster for mysql 8安装配置启动重启集群
  • 动手实现自己的 JVM——Go!(ch03)
  • 烧烤炉出口亚马逊欧盟站CE认证EN1860安全标准
  • Golang的并发编程案例详解
  • LeetCode1287
  • 【SpringBoot苍穹外卖】debugDay04
  • TikTok 多账号管理与自动化运营:矩阵系统功能全解析