PAT 1018 Public Bike Management(Dijkstra,链式前向星)

这篇博客介绍了作者在解决PAT题1018PublicBikeManagement时的经历,探讨了如何使用Dijkstra算法优化路径搜索,并通过邻接矩阵和链式前向星实现。作者在代码实现中遇到挑战,最终优化了优先队列的Dijkstra算法,解决了单程运输问题,避免了无限往复转移。文章通过实例分析了错误案例,解释了正确解题思路。

题目链接:1018 Public Bike Management
参考代码的原址
看了好多篇题解,看他们都是用邻接矩阵建的图,但感觉用邻接表太慢,而且他们的dijkstra算法的复杂度都在O(E2+V)…感觉这样不好,就自己试着照他们的写了下,用了优先队列优化了下dijkstra,建图用了链式前向星建图,但代码还是写了好长好长,比参考的代码还长,有些郁闷,前前后后花了五个小时,自己的第一道PAT题(原因是为了拿牛客网的那张50块的优惠券!在牛客网是第一道题)

自己先总结一下,这个题还挺有意思的,首先dijkstra建个树,但每个节点可能存在多个隐藏的父节点,我们这里用vector< int >pre来进行表示,自己最开始一直想把它当成个网络流来做,后来看了别人的题解才知道,只是个单条路线问题,第一次写的dfs,以为要么拿走的自行车是0个,要么带出去的自行车是0个,一条路上的节点间可以无限往复转移携带,后来才发现,都是单程的,仅就一去一回。开始自己还考虑炸的情况,就是remain太多了超出了每个节点的最大承载量,后来自己才意识,联系到现实生活,不管是那些remain还是need,一直都是放在运输车的上的…不会放到节点中暂存,所以也就更不会爆了。


第一次的PAT题做了我五个小时,竟是如此的痛苦...明明刚从蓝桥杯的训练中走了出来

成功的代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

struct edge {
   
   
	int to, next, dis;
};
struct node {
   
   
	int pos;
	int dis;
	bool operator<(const node& a)const
	{
   
   
		return a.dis < dis;
	}
};
const int maxn = 1e4 + 7;
int cnt = 0;
int s = 0;
int g[maxn][maxn];	//边图
int head[maxn];
edge e[maxn];
int vis[maxn];
int dis[maxn];
int c[maxn];//vertice contain
vector<int>pre[maxn];//收集每个节点可能的前驱节点
vector<int>tem[maxn];//收集每个节点临时可能的前驱节点
priority_queue<node>q;
void add_edge(int u,int v,int d)
{
   
   
	cnt++;
	e[cnt].next = head[u];
	head[u]=cnt;
	e[cnt].to = v;
	e[cnt].dis = d;
}
void dijkstra()
{
   
   
	memset(dis, 0x7f, sizeof dis);
	dis[s] = 0;
	q.push(node{
   
   s,0});
	while (!q.empty())
	{
   
   
		node vertice = q.top();
		q.pop();
		int x = vertice.pos;
		if (vis[x])
			continue;
		vis[x] = 1;
		for (int i = head[x]; i; i = e[i].next)
		{
   
   
			int y = e[i].to;
			if (dis[y] > dis[x] +
### Dijkstra Algorithm Implementation Using Linked Forward Star For solving problems like the one mentioned on Luogu platform, specifically problem 1821 which involves shortest path finding in graphs, implementing Dijkstra's algorithm with a linked forward star structure can be highly efficient due to its ability to handle sparse graphs effectively. The following C++ code demonstrates how this combination works: ```cpp #include <iostream> #include <vector> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; struct Edge { int v; // destination node index int w; // edge weight int next; // pointer to the next edge of the same source node }; int head[10005], dis[10005]; bool vis[10005]; Edge edges[100005]; void add_edge(int u, int v, int w, int& idx) { edges[idx].v = v; edges[idx].w = w; edges[idx].next = head[u]; head[u] = idx++; } // Function to initialize all distances as infinite and visited flags as false. void init(int n) { fill(dis, dis + n + 1, INF); fill(vis, vis + n + 1, false); } pair<int,int> dijkstra(int s, int t, int n) { priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq; dis[s] = 0; pq.push({dis[s], s}); while (!pq.empty()) { auto cur = pq.top(); pq.pop(); int d = cur.first; int u = cur.second; if (vis[u]) continue; vis[u] = true; for (int i = head[u]; ~i; i = edges[i].next) { int v = edges[i].v; int w = edges[i].w; if (dis[v] > dis[u] + w && !vis[v]) { dis[v] = dis[u] + w; pq.push({dis[v], v}); } } } return make_pair(t, dis[t]); } ``` In order to use the above function `dijkstra`, it is necessary first to call `init` followed by adding each graph edge via `add_edge`. The parameters passed into these functions should match those defined within your specific problem statement or dataset requirements[^1].
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值