首页 > 其他分享 >关于 图论建模 的一些技巧

关于 图论建模 的一些技巧

时间:2024-05-20 21:42:32浏览次数:14  
标签:图论 dist 技巧 int max 边权 决策 建模 分层

分层图思想

分层图在 最短路 中经常用到。

直观上讲,就是将一个图复制 k 倍,互相是平行的,即互不影响,分层图 两两之间 会有 决策边 相连。

这就等价于要在一个图上进行 k 次决策,对于每次决策,不影响图的结构,只影响目前的状态或代价。一般将决策前的状态和决策后的状态之间连接一条权值为决策代价的边,也就是决策边。

一般有两种方法:

  • 建图直接建 k + 1 层;
  • 数组多开一维记录决策信息;(与dp思想相关)

Part Ⅰ

P1948 [USACO08JAN] Telephone Lines S

题目说明可以进行 k 次免费决策,考虑直接建 k + 1 层图。

对于一条路径 (x, y, w) ,如果考虑决策免费,那就等价于向下一状态连一条 0 边权的单向边,即 (x, y + n, 0)

建图完就可以直接 dij 跑图,

同时注意到所求答案要求是 一条满足条件的路径上的最大边权的最小值

也就是,对于当前访问到的点 y,(x, y, w) ,如果 1 ~ y 上原先记录的最小最大边权比前驱点 x 所记录的以及当前 w 比较都大了,

即 \(dist_y > \max(dist[x],~w)\) ,说明可以更新 \(dist_y = \max(dist[x],~w)\),

这样就做到了 最小化最大边权的收敛


注意:可能存在 k 次免费决策不必全部用完就可到达终点的情况,所以 k 次决策可能不全使用,因此对每个点要考虑当前状态不使用决策直接转移到下一状态,即连 (i, i + n, 0)

边数计算一下是要 \(2(k + 1)M + 2Mk + kN = 4MN + N^2\),大概 5e7 的样子,不会超空间。

所以,很重要的是 分层图建图要考虑建图思路会不会超空间

#include <bits/stdc++.h>
#define re register int 
#define max(x, y) (x > y ? x : y)
using namespace std;
typedef pair<int, int> pii;
const int N = 1e6 + 10, M = 5e7 + 10, inf = 0x3f3f3f3f;
struct edge
{
	int to, w, next;
}e[M];
int top, h[N], dist[N];
int n, m, k;
bool vis[N];
priority_queue< pii, vector<pii>, greater<pii> > q;

inline void add(int x, int y, int w)
{
	e[++ top] = (edge){y, w, h[x]};
	h[x] = top;
}

inline void build(int a, int b, int c)
{
	add(a, b, c); 
	add(b, a, c);
	for (re i = 1; i <= k; i ++)
	{
		add(i * n + a, i * n + b, c);
		add(i * n + b, i * n + a, c);
		
		add((i - 1) * n + a, i * n + b, 0);
		add((i - 1) * n + b, i * n + a, 0);
	}		
}

inline bool dijkstra()
{
	memset(vis, false, sizeof(vis));
	for (re i = 0; i <= (k + 1) * n; i ++) dist[i] = inf;
	
	dist[1] = 0;
	q.push(make_pair(0, 1));
	
	while (!q.empty())
	{
		int x = q.top().second; q.pop();
		if (vis[x]) continue;
		vis[x] = true;
		
		for (re i = h[x]; i; i = e[i].next)
		{
			int y = e[i].to, w = e[i].w;
			if (dist[y] > max(dist[x], w))
			{
				dist[y] = max(dist[x], w);
				q.push(make_pair(dist[y], y));
			}
		}
	}
	
	return (dist[(k + 1) * n] == inf ? false : true);
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	
	cin >> n >> m >> k;
	while (m --)
	{
		int a, b, c; cin >> a >> b >> c;
		build(a, b, c);
	}
	for (re i = 1; i <= n; i ++)
		for (re j = 1; j <= k; j ++)
			add((j - 1) * n + i, j * n + i, 0);
			
	if (dijkstra()) cout << dist[(k + 1) * n] << '\n';
	else cout << "-1\n";
	
	return 0;
}

标签:图论,dist,技巧,int,max,边权,决策,建模,分层
From: https://www.cnblogs.com/hi-zwjoey/p/18202847

相关文章

  • Kubernetes Pod调度:从基础到高级实战技巧
    本文深入探讨了Kubernetes中的Pod调度机制,包括基础概念、高级调度技术和实际案例分析。文章详细介绍了Pod调度策略、Taints和Tolerations、节点亲和性,以及如何在高流量情况下优化Pod调度和资源管理。关注【TechLeadCloud】,分享互联网架构、云服务技术的全维度知识。作者拥有10......
  • 线程安全使用 HashMap 的四种技巧
    这篇文章,我们聊聊线程安全使用HashMap的四种技巧。1方法内部:每个线程使用单独的HashMap如下图,tomcat接收到到请求后,依次调用控制器Controller、服务层Service、数据库访问层的相关方法。每次访问服务层方法serviceMethod时,都会在方法体内部创建一个单独的HashMap,......
  • 整理C语言预处理过程语法的实用方法与技巧
    预处理目录预处理一、宏定义数值宏常量字符串宏常量用define宏定义注释符号?程序的编译过程预处理中宏替换和去注释谁先谁后?如何写一个不会出现问题的宏函数do-while-zero结构do-while-zero的评价宏定义中的空格宏只能在main函数上面定义吗?宏的作用范围#undef宏替换是在函数调用......
  • puppeteer使用一些技巧简单说明
    puppeteer是一个nodejs包提供了方便的基于devtools协议进行chrome/chromium控制,puppeteer默认运行在无头模式以下是对于puppeteer使用的一些简单总结一些问题browser&&page对象复用问题实际上还是结合实际,个人建议减少复用,除非自己对于browser&&page进行了比较......
  • Flex布局-margin 妙用技巧
    在flex布局中,通过对子项设置margin-auto;的方式去吃掉剩余空间,这种小技巧在很多时候能极大简化我们的布局哦.单元素水平垂直居中如果父容器是flex,要实现元素水平垂直居中,直接在容器项添加:display:flex;justify-content:center;align-items:center;但......
  • C/C++技巧
    1.三目运算符语法:表达式1?表达式2:表达式3。表达式1为真则执行表达式2,否则执行表达式3。相比if语句,三目运算符短小简洁,适当使用可以提高代码可读性。另外,如果三目运算符返回左值,可以继续赋值。举例#include<iostream>usingnamespacestd;intmain(){system("......
  • Transformers 加速的一些常用技巧
    前言 本文介绍了一些Transformers常用的加速策略。本文转载自DeephubImba仅用于学术分享,若侵权请联系删除欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最新技术跟踪、经典论文解读、CV招聘信息。CV方向的准研究生们,未来三年如何度过?招聘高光谱图像、语义分割、di......
  • 农村高中生源转型期提升学生二次函数建模能力的课堂探究
       通过结合具体的数学问题,引导高中生深入分析问题,有效地构建求解问题的数学模型,可以使学生逐步掌握数学问题求解的基本思路以及模型建构的方法与注意事项。但是离开了反复训练,无法从根本上提升高中生的数学建模能力。因此,在平时的高中数学教学中,教师要注意结合数学教学的内......
  • WPS技巧——MARK住
    一、如何对一列数据进行相同操作,比如全都添加双引号https://www.jiachong.com/wps/340708.html1.首先打开表格,按Ctrl+C复制第一个单元格内容,2.然后把复制的单元格内容按Ctrl+V粘贴到与其齐平的空白单元格里(即辅助列),在辅助列的单元格内容中输入双引号,3.最后将鼠标点击到......
  • 交流沟通技巧2
    一,生气时,一定要安抚好别人的情绪,在进行交流沟通。自己生气时也一定要先平息自己的心情那么如何安抚好别人的情绪呢??? 1.倾听和理解:倾诉具有一种积极的心理效应情绪的宣泄:倾诉提供了一个出口,让生气的情绪得以宣泄。通过表达愤怒、不满或困扰,我们可以释放内心的压力,减少紧张感和......