YTU3745:ROADS C++ DFS

该文是一个关于图论和算法的问题,描述了如何使用深度优先搜索(DFS)解决从城市1到城市N的最短路径问题,考虑了路径长度和过路费,并在资金有限的情况下找到可行路径。代码示例中,使用邻接列表存储城市间的道路信息,并通过DFS遍历所有可能的路径。
摘要由CSDN通过智能技术生成

题目描述

有 NNN 个城市,编号为 111 ~ NNN。城市间有 NNN 条单向道路,每条道路连接两个城市,有长度和过路费两个属性。Bob 只有 KKK 块钱,他想从城市 111 走到城市 NNN。问最短需要走多长的路。如果到不了 NNN,输出 −1-1−1。其中,2≤N≤1002 \le N \le 1002≤N≤100;0≤K≤100000 \le K \le 100000≤K≤10000;1≤R≤100001 \le R \le 100001≤R≤10000;每条路的长度为 LLL,1≤L≤1001 \le L \le 1001≤L≤100;每条路的过路费为 TTT,0≤T≤1000 \le T \le 1000≤T≤100。

输入

第一行是 KKK,第二行是 NNN,第三行是 RRR。接下来有 RRR 行,每行有 444 个整数 s,e,L,Ts, e, L, Ts,e,L,T,表示从城市 sss 到城市 eee 有一条单向路(可以沿该路从 sss 走到 eee,但不能沿该路从 eee 走到 sss),其长度是 LLL,过路费是 TTT。

输出

只有一行,就是问题答案。

输入输出样例

样例输入 #1

5
6
7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2

样例输出 #1

11

我就一鶸,直接上代码!!!

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int n,money,roads;//城市数量,钱的数量,道路的数量
int min_money=0,min_distance=0;//正在走的路径的长度和花销
int s=1<<30;//最小的距离
bool sle[105];
int minS[105][10005];

struct road
{
	int a,b;
	int l;
	int cost;
};
vector<vector<road>> city(105);//邻链表,类似二维数组

void dfs(int t1)
{
	if(t1==n)
	{
		s=min(s,min_distance);
		return;
	}
	for(int i=0;i<city[t1].size();i++)
	{
		int t2=city[t1][i].b;
		if(!sle[t2])
		{
			int ccc=min_money+city[t1][i].cost;
			if((min_money+city[t1][i].cost)>money)
				continue;
			if((min_distance+city[t1][i].l)>=s||(min_distance+city[t1][i].l)>=minS[t2][ccc])
				continue;
			min_money+=city[t1][i].cost;
			min_distance+=city[t1][i].l;
			minS[t2][ccc]=min_distance;
			sle[t2]=true;
			
			dfs(t2);
			
			min_money-=city[t1][i].cost;
			min_distance-=city[t1][i].l;
			sle[t2]=false;
		}
	}
	return;
}

int main()
{
	memset(sle,false,sizeof(sle));
	cin>>money>>n>>roads;
	for(int i=0;i<roads;i++)
	{
		road x;
		cin>>x.a>>x.b>>x.l>>x.cost;
		city[x.a].push_back(x);
	}
	for(int i=0;i<105;i++)
		for(int j=0;j<10005;j++)
			minS[i][j]=1<<30;
	sle[1]=1;
	dfs(1);//从城市1开始深搜
	if(s<(1<<30))
		cout<<s<<endl;
	else
		cout<<"-1"<<endl;
	return 0;//庄严的结束程序吧!!!
}

易大师说过:一个真正的大师永远是个学徒

参考了CSDN上很多大佬的解法,希望大佬们原谅!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值