最少换乘(最短路+恶心的输入)acm寒假集训日记22/1/3 or 22/1/4

题目如下:

 

AC代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 2009;
int d[N][N];
int dis[N];
int vis[N];
char s[N];
int jl[N];
int main()//目标1->n; 
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		memset(d, inf, sizeof d);
		int n, m;
		scanf("%d %d", &m, &n);
		getchar();
		while (m--)
		{
			int cnt = 0;
			char c = 1;
			while(c!=-1 && c!='\n')	//'\n'
			{
				scanf("%d",&jl[ ++cnt ]);
				c=-1;
				scanf("%c",&c);
			}
			for (int i = 1; i < cnt; i++)
			{
				for (int j = i + 1; j <= cnt; j++)
					d[jl[i]][jl[j]] = 1;
			}
		}
		for (int i = 1; i <= n; i++)
		{
			dis[i] = d[1][i];
			vis[i] = 0;//
		}
		dis[1] = 0;
		vis[1] = 1;
		for (int i = 1; i <= n; i++)
		{
			int ans = inf, k = 0;
			for (int j = 1; j <= n; j++)
			{
				if (!vis[j] && dis[j] < ans)
				{
					k = j;
					ans = dis[j];
				}
			}
			vis[k] = 1;
			if (ans == inf)
				break;
			for (int j = 1; j <= n; j++)
			{
				if (!vis[j] && dis[j] > dis[k] + d[k][j])
					dis[j] = dis[k] + d[k][j];
			}
		}

		if (dis[n] >= inf)
			printf("NO\n");
		else
			printf("%d\n", dis[n]-1);
	}
}

代码解析(题解):

这个题可以说是: 处理输入 + 构建图 + 最短路板子(Dijkstra算法

这道题的难点其实是输入,一行输入代表该路公交 可以到的站

那我们这样处理:

while(c!=-1 && c!='\n')	//'\n'
{
	scanf("%d",&jl[ ++cnt ]);
	c=-1;
	scanf("%c",&c);
}

将数据读入后,接下来是图的构建:

因为我们的目标是最少换乘,那我们一辆车到该车任意站可以设置为1,但必须是从左到右(开双重for循环来解决这个问题)

代码实现:

for (int i = 1; i < cnt; i++)
	{
		for (int j = i + 1; j <= cnt; j++)
		d[jl[i]][jl[j]] = 1;
	}

 最后用Dijkstra算法就可以得到答案了!
注意:得答案的时候再-1,因为一开始坐的车不算换乘!!!

if (dis[n] >= inf)
	printf("NO\n");
else
	printf("%d\n", dis[n]-1);

最后,感谢大家的阅读!!!

ps:

今天回家了(写这篇文章时,人在高铁上),怕疫情严重 到时候封城回不去,所以提前到4号回家(原计划9号回去)

但集训继续(线上)!!!

回家要干什么呢?

开始卷!!!

开卷!!

卷!


 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Joanh_Lan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值