1585. 【2024 年中山市东区】旅行(tour)

给定小岛数量n和轮船连接情况,计算Jimmy从任一岛屿出发并结束于不同岛屿的旅行计划总数,使用图算法解决

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

由于在某谷上举办的比赛反响热烈,参与人数众多,Jimmy 得到了一笔客观的广告费!于是,他决定来一场“说走就走的旅行”。

Jimmy 一共有 N 座想去的小岛,编号为 1⋯N。小岛之间一共有 M 班轮船,其中第 i 班轮船可以带 Jimmy 从第 xi​ 个小岛去第 yi​ 个小岛,但是 Jimmy 搭不了回程的轮船,因此他不能坐第 i 班轮船从第 yi​ 个小岛回到第 xi​ 个小岛。

在去之前 Jimmy 想做一个旅行计划。他可以选择从某个小岛开始旅行,途中搭船经过若干个其他的小岛(也可以不经过其他小岛),最后到达某个小岛并结束旅行。当然,Jimmy 也可以选择在一个小岛上一直度假,因此他的旅行可以在同一个岛上开始和结束。Jimmy 只关心旅行在哪开始以及在哪结束。他觉得,如果一个旅行计划的开始小岛或者结束小岛与其他的计划不同,那么这两个计划就算是不同的。

Jimmy 现在想知道他一共有多少种不同的旅行计划。你能帮帮他吗?

输入

第一行两个正整数 N,M,分别表示小岛的数量,以及轮船的班数。

接下来的 M 行,每行两个正整数 xi​,yi​,表示第 i 班轮船可以从第 xi​ 个小岛去到第 yi​ 个小岛。

输出

一行一个整数,表示不同的旅行计划种数。

样例数据
输入 #1 复制
3 3
1 2
2 3
3 2
输出 #1 复制
7
输入 #2 复制
3 0
输出 #2 复制
3
输入 #3 复制
4 4
1 2
2 3
3 4
4 1
输出 #3 复制
16
数据范围限制

对于 100% 的数据,满足:

  • 1≤N≤2000
  • 0≤M≤2000
  • 1≤xi​,yi​≤N
  • xi​=yi​
  • 保证不存在完全相同的轮船班次,即 (xi​,yi​) 必定互不相同
提示

【样例 1 解释】

一共有 7 种不同的旅行计划,分别为 (1,1), (1,2), (1,3), (2,2), (2,3), (3,2), (3,3),其中 (p,q) 表示 Jimmy 从第 p 个小岛开始旅行,在第 q 个小岛结束。注意,由于 Jimmy 无法从第 2 个小岛前去第 1 个小岛,因此不存在 (2,1) 这种旅行方案。同理,也不存在 (3,1) 这种旅行方案。

【样例 2 解释】

Jimmy 没有任何轮船可以搭,他只能在同一个小岛上开始和结束旅行,一共有 3 个小岛,因此一共有 3 种不同的旅行方案。

【样例 3 解释】

Jimmy 可以在任意小岛上开始旅行、并在任意小岛上结束旅行,因此总的旅行方案数为 4 × 4 = 16 种。

代码:

#include <bits/stdc++.h>
using namespace std;
int ans=0,a[2001][2001],f[4001],w[2001][2001],num[2001],dis[2001],b[4001];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		w[x][y]=1;
		a[x][++num[x]]=y;
	}
	for(int i=1;i<=n;i++)
	{
		int h=0,t=1;
		memset(b,0,sizeof(b));
		memset(f,0,sizeof(f));
		for(int j=1;j<=n;j++) dis[j]=1e9+7;
		dis[i]=0;
		b[i]=1;
		f[1]=i;
		do
		{
			h++;
			h=((h-1)%2001)+1;
			int u=f[h];
			b[u]=0;
			for(int j=1;j<=num[u];j++)
			{
				if(dis[a[u][j]]>dis[u]+w[u][a[u][j]])
				{
					dis[a[u][j]]=dis[u]+w[u][a[u][j]];
					if(b[a[u][j]]==0)
					{
						t++;
						t=((t-1)%2001)+1;
						f[t]=a[u][j];
						b[a[u][j]]=1;
					}
				}
			}
		}while(h!=t);
		for(int j=1;j<=n;j++)
		{
			if(dis[j]!=1e9+7)
			{
				ans++;
				//printf("%d %d\n",i,j);
			}
		}
	}
	printf("%d",ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值