最短路+二分题目整理

这篇具有很好参考价值的文章主要介绍了最短路+二分题目整理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前往奥格瑞玛的道路

题目链接
\(\qquad\)题目要求最小化最大费用,显然是使用二分答案,二分答案首先应该看限制目标,此处的限制是血量限制,而目标是费用目标。这种情况我们可以二分费用,然后在图上跑最短路判定血量是否满足。
\(\qquad\)对于check函数,我们去判定是否存在一条道路使得最高费用不超过mid,并且小号血量不超过hp,我们对于所有目的点费用不超过mid的点跑最短路,判定是否满足hp的限制即可。

代码

#include <bits/stdc++.h>
#define pb emplace_back

using namespace std;
using PII = pair<int, int>;

const int N = 1e5 + 10;
vector<PII> h[N];
int n, m, hp, hh, tt;
int cost[N], dist[N], st[N], q[N];

bool check(int mid) {
	if (cost[1] > mid) return 0;
	memset(dist, 0x3f, sizeof dist);
	memset(st, 0, sizeof dist);
	hh = tt = 0;
	q[0] = 1, st[1] = 1, dist[1] = 0;

	while (hh <= tt) {
		int t = q[hh ++ ];
		st[t] = 0;
		for (auto k : h[t]) {
			int v = k.first, w = k.second;
			if (cost[v] > mid) continue ;
			if (dist[v] > dist[t] + w) {
				dist[v] = dist[t] + w;
				if (!st[v]) st[v] = 1, q[ ++ tt] = v;
			}
		}
	}

	return dist[n] <= hp;
}

int main() {
	scanf("%d%d%d", &n, &m, &hp);
	for (int i = 1; i <= n; i ++ ) scanf("%d", &cost[i]);
	while (m -- ) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		h[u].pb(v, w), h[v].pb(u, w);
	}

	int l = 0, r = 1e9 + 1;
	while (l < r) {
		int mid = l + r >> 1;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	if (r == 1e9 + 1) puts("AFK");
	else printf("%d\n", r);

	return 0;
}

Telephone Lines S

题目链接
\(\qquad\)我们可以取消 \(\le K\) 条道路的价值,并取得剩下的道路中最贵的。很容易想到一个贪心的策略,那就是取消最贵的 \(K\) 条路的价值,这样我们剩下的就是第 \(K + 1\) 贵的边了。
题目让我们最小化这个值,也就是让我们最小化 K + 1 大值,也可以采用二分。当然如果比它大的值小于 \(K\) 的时候,直接全部删除即可。
\(\qquad\)二分之前我们同样先看下限制目标,这题的限制应该是更大值限制,而目标是最小费用目标,所以我们可以二分一下费用,并且判定是否在 \(1\sim N\)的路上有不超过 \(K\) 条边比它大即可。

代码

#include <bits/stdc++.h>
#define pb emplace_back

using namespace std;
using PII = pair<int, int>;

const int N = 1010;
vector<PII> h[N];
int n, m, k, st[N], dist[N];

bool check(int mid) {
	memset(dist, 0x3f, sizeof dist);
	memset(st, 0, sizeof st);
	queue<int> q;

	q.push(1), st[1] = 1, dist[1] = 0;
	while (q.size()) {
		int t = q.front();
		q.pop(), st[t] = 0;
		for (auto k : h[t]) {
			int v = k.first, w = k.second;
			int W = w > mid;
			if (dist[v] > dist[t] + W) {
				dist[v] = dist[t] + W;
				if (!st[v]) st[v] = 1, q.push(v);
			}
		}
	}

	return dist[n] <= k;
}

int main() {
	scanf("%d%d%d", &n, &m, &k);
	while (m -- ) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		h[u].pb(v, w), h[v].pb(u, w);
	}

	int l = 0, r = 1e6 + 1;
	while (l < r) {
		int mid = l + r >> 1;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	printf("%d\n", r == 1e6 + 1 ? -1 : r);

	return 0;
}

Sightseeing Cows G

题目链接
\(\qquad\)这题是平均值最小问题,可以二分平均值,没有特殊的限定条件。
\(\large mid\le \frac{\sum w}{\sum t}\Rightarrow mid\times \sum t \le \sum w\Rightarrow mid\times \sum t - \sum w <= 0\)
所以我们是在原图上判负环和零环即可。

#include <bits/stdc++.h>
#define pb emplace_back

using namespace std;
using PII = pair<int, int>;

const int N = 1010;
vector<PII> h[N];
int n, m, st[N], f[N];
double dist[N];

bool dfs(int u, double mid) {
	st[u] = 1;
	for (auto k : h[u]) {
		int v = k.first, w = k.second;
		double W = w * mid - f[v];
		if (dist[v] >= dist[u] + W) {
			dist[v] = dist[u] + W;
			if (st[v]) { st[v] = 0; return 1; }
			if (dfs(v, mid)) { st[v] = 0; return 1; }
		}
	}
	return st[u] = 0;
}

bool check(double mid) {
	int ring = 0;
	memset(st, 0, sizeof st);
	for (int i = 1; i <= n; i ++ ) {
		if (ring) break ;
		if (st[i]) continue ;
		ring |= dfs(i, mid);
	}
	return ring;
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i ++ ) scanf("%d", &f[i]);
	while (m -- ) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		h[u].pb(v, w);
	}

	double l = 0, r = 1001;
	while (r - l > 1e-4) {
		double mid = (l + r) / 2;
		if (check(mid)) l = mid;
		else r = mid;
	}
	printf("%.2lf\n", r);

	return 0;
}

Word Rings

题目链接
\(mid\le \frac{\sum w}{cnt}\Rightarrow mid\times cnt\le \sum w\Rightarrow \sum (mid-w)\le 0\)
判一下零环和负环即可。
注意的是这里的建图方式。我们要求图上包含的信息是:点一定是给定字符串的头两个或尾两个字符;字符串的长度。我们由此可以想到只对于每个字符串连接首尾两个的字符,边权为字符串长度,然后与上题相同。文章来源地址https://www.toymoban.com/news/detail-429731.html

#include <bits/stdc++.h>
#define pb emplace_back

using namespace std;
using PII = pair<int, int>;

const int N = 1010;
vector<PII> h[N];
int n, m, st[N];
double dist[N];

bool dfs(int u, double mid) {
	st[u] = 1;
	for (auto k : h[u]) {
		int v = k.first, w = k.second;
		double W =  mid - w;
		if (dist[v] > dist[u] + W) {
			dist[v] = dist[u] + W;
			if (st[v]) { st[v] = 0; return 1; }
			if (dfs(v, mid)) { st[v] = 0; return 1; }
		}
	}
	return st[u] = 0;
}

bool check(double mid) {
	int ring = 0;
	memset(st, 0, sizeof st);
	for (int i = 1; i <= 676; i ++ ) {
		if (ring) break ;
		if (st[i]) continue ;
		ring |= dfs(i, mid);
	}
	return ring;
}

int main() {
	while (scanf("%d", &n), n) {
		for (int i = 1; i <= 676; i ++ ) h[i].clear();
		string s;
		for (int i = 1; i <= n; i ++ ) {
			cin >> s;
			int a, b, sz = s.size();
			a = (s[0] - 'a') * 26 + s[1] - 'a' + 1;
			b = (s[sz - 2] - 'a') * 26 + s[sz - 1] - 'a' + 1;
			h[a].pb(b, sz);
		}
		if (!check(0)) puts("No solution");
		else {
			double l = 0, r = 100001;
			while (l < r - 1e-5) {
				double mid = (l + r) / 2;
				if (check(mid)) l = mid;
				else r = mid;
			}
			printf("%.2lf\n", r);
		}
	}

	return 0;
}

到了这里,关于最短路+二分题目整理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用邻接矩阵实现有向图最短路径Dijkstra算法 题目编号:1136

    用邻接矩阵存储有向图,实现最短路径Dijkstra算法,图中边的权值为整型,顶点个数少于10个。 部分代码提示: #include #include using namespace std; const int MaxSize = 10; const int INF = 32767; class MGraph { public: MGraph(char a[], int n, int e); private: char vertex[MaxSize]; int arc[MaxSize][MaxSize]; int vertexNum,

    2024年02月01日
    浏览(80)
  • 【A*算法——清晰解析 算法逻辑——算法可以应用到哪些题目】例题1.第K短路

    欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示:重难点★✔ 蓝色文字表示:思路以及想法★✔ 如果大家觉得有帮助的话,感谢大家帮忙 点赞!收藏!转发! A*算法是什么

    2024年02月05日
    浏览(34)
  • AI题目整理

    Batch size是指一次迭代过程中,输入到神经网络的样本数量。 batchsize太小的缺点: ①耗时长,训练效率低。 ②训练数据就会非常难收敛,从而导致欠拟合。 batchsize增大的优缺点 ①大的batchsize减少训练时间 ②大的batchsize所需内存容量增加 ③大的batch size梯度的计算更加稳定

    2024年02月03日
    浏览(36)
  • 电子电路原理题目整理(1)

    1.电压源和电流源的区别? 电压源在不同的负载电阻下可提供恒定的负载电压,而电流源对于不同的负载电阻可产生恒定的负载电流。 2.在计算负载电流时,什么情况下必须考虑内阻? 对于电压源,当电源内阻大于负载电阻的0.01倍时,内阻不可忽略。 对于电流源,当电源内

    2024年02月10日
    浏览(37)
  • 山东大学2022-2023多核复习课题目答案整理/往年题整理

    快说谢谢刘老师,一般按照复习题考原题!!! 下面是2022-2023的版本,每年基本不变,今年新增CUDA部分,本文已包含相关考点 MPI 基本使用方法在笔记中 矩阵向量乘法中,行数或者列数不能被线程数整除的情况下,如何分配数据? 基本思路就是小于余数的rank多算一份,然后

    2024年02月07日
    浏览(50)
  • 离散数学题目收集整理练习(期末过关进度50%)

    ✨ 博主: 命运之光 🦄 专栏: 离散数学考前复习(知识点+题) 🍓 专栏: 概率论期末速成(一套卷) 🐳 专栏: 数字电路考前复习 ✨ 博主的其他文章: 点击进入博主的主页​​​​​ 前言: 身为大学生考前复习一定十分痛苦,你有没有过以下这些经历: 1.啊明天要考

    2024年02月09日
    浏览(63)
  • LeetCode-题目整理【3】:买卖股票的最佳时机

    买卖股票的最佳时机 都是求最大利润,但是在没有限制,如121和122,动态规划稍微复杂一些,建议不用,到最后两道难题,题目有限制,使用动态规划通过求解子问题的最优解来逐步求解原问题的最优解。 买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i]

    2024年01月23日
    浏览(66)
  • 概率论的学习和整理--番外12:2个概率选择比较的题目

    目录 1 要解决的题目 2 先说结论,后面解释原因 2.1 先考虑期望,期望要尽量大,但比然有限制 2.2  再考虑方差,在期望给定前提下,尽量减小方差,稳定体验 2.3 结论:先考虑期望,再考虑方差 3 算法 3.1 错误算法 3.2  正确算法1,直接解方程 3.3 正确算法2,用条件期望求解

    2024年02月16日
    浏览(43)
  • 【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值

    《博主简介》 小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌ 更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍 感谢小伙伴 们点赞、关注! class   Solution :      def   mySqrt ( self ,  x :   int )   -   int :       

    2024年02月04日
    浏览(65)
  • 华为OD机试(B、C卷)、机考,200分的题目整理如下,冲满分必备

    2023 年参加华为 OD 机试,你收到的短信邀请链接中提及的应该是 2022Q4 或者 2023Q1 都是 A 卷。 5月1日之后,有部分朋友收到的是 B 卷,那么恭喜你看到本文了,快抓紧刷吧。 B 卷新题库正在更新中…… O(∩_∩)O 只要是这样的试卷标题,那表示你使用的就是华为 OD 的新题库了。

    2024年02月03日
    浏览(83)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包