SP18966 VACATION - Vacation Planning 题解

题目传送门

题意简述

给定一张有向带权图,有 Q Q Q 个请求,每个请求给出点 a i a_i ai b i b_i bi,费用为 a i a_i ai 经过点 1 → K 1 \rightarrow K 1K 中的至少一个到达 b i b_i bi 的最小权值和。求出可行的请求数和最小费用和。

分析

有多个询问,很明显是多源最短路,求多源最短路可以用 Floyd,也可以调用 n n n 次 Dijkstra。

核心代码

int dis[205][205];
bool vis[205][205];

void Dijkstra(int s) {
	memset(dis[s] + 1, 0x3f3f3f3f, sizeof dis[s] + 1);
	memset(vis[s] + 1, 0, sizeof vis[s] + 1);
	struct poi {
		int d, p;
		bool operator<(const poi& x)const { return d > x.d; }
	};
	priority_queue <poi>q;
	dis[s][s] = 0;
	q.push({ 0, s });
	while (!q.empty())
	{
		int u = q.top().p; q.pop();
		if (vis[s][u])continue;
		vis[s][u] = true;
		for (int i = 0; i < g[u].size(); i++)
		{
			int v = g[u][i].v;
			if (dis[s][v] > dis[s][u] + g[u][i].w) {
				dis[s][v] = dis[s][u] + g[u][i].w;
				q.push({ dis[s][v],v });
			}
		}
	}
}

//主程序调用

for (int i = 1; i <= n; i++)Dijkstra(i);

//这样,dis[i][j]就是i到j的最短路径了

询问部分,依然是类似 Floyd 插 1 → K 1 \rightarrow K 1K 个点进行松弛操作,其他题解写得很清楚,这里不再赘述。

Over. \text{Over.} Over.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值