首页 > 其他分享 >图论 - 某进制分组 - P5304 旅行者

图论 - 某进制分组 - P5304 旅行者

时间:2024-01-14 10:44:28浏览次数:27  
标签:图论 进制 vis int 二进制 分组 ans P5304 dis

P5304旅行者

\(\mathtt{TAGS}\): 多源多汇最短路,二进制分组
\(\mathtt{ESTIMATION}\):非常好二进制分组,让我的大脑旋转

题意简述

给定 \(k\) 个点和一张有向图,求以这 \(k\) 个点为起点和终点的最短路中最短的一条的长度。

First. 怎么求多源多汇最短路

solution.1

超级源点超级汇点,超级源点以 \(0\) 的权值连接所有起点,所有终点以 \(0\) 的权值连向超级汇点,从超级源点出发,到超级汇点,即为多源多汇的最短路的长度。

solution.2

对于 dijkstra 算法,直接把所有源点初始放进 \(s\) 集合里,\(dis\) 设为 \(0\),正常跑一遍即可。

But,这道题的起点和终点是不固定的!

所以第一种做法先暂不考虑。

Second. 怎么分起点终点

*MikeZ = & shuffle

直接 shuffle,随机分组!
-- by MikeZ

很不幸的是,这题没有很多时间让你反复跑随机化来获得正确答案,正确率不高。

二进制分组

对于每个标记的节点 \(u\),考虑它的二进制表示法,按照每一位二进制为 \(0\) 或是 \(1\) 来确定它是哪个集合的。而且由于二进制某一位不同的数一定就不相等,所以不会出现起点 = 终点的情况。

Code

const int N = 2e5 + 10;
int n, m, k;
vector< pi > G[N];
ll dis[N];
bool vis[N];
int li[N];
ll dijkstra (int pos, int val) { // pos 表示 二进制的第几位,val表示是1为S集还是 0 为 S 集
	priority_queue<pi, vector<pi>, greater<pi> > q;
	memset(dis, 0x3f, sizeof dis);
	memset(vis, 0, sizeof vis);
	for (int i = 1; i <= k; i ++) {
		int x = li[i];
		if(((x >> (pos - 1)) & 1) == val) {
			dis[x] = 0;
			q.push({0, x});
		}
	}
	while(!q.empty()) {
		int u = q.top().second;
		q.pop();
		if(vis[u]) continue;
		vis[u] = 1;
		for (auto e : G[u]) {
			int v = e.first, w = e.second;
			if(dis[u] + w < dis[v]) {
				dis[v] = dis[u] + w;
				q.push({dis[v], v});
			}
		}
	}
	ll minn = 0x3f3f3f3f3f3f3f3f;
	for (int i = 1; i <= k; i ++) {
		int x = li[i];
		if(((x >> (pos - 1)) & 1) != val) {
			minn = min(dis[x], minn);
		}
	}
	return minn;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	while(t --) {
		cin >> n >> m;
		for (int i = 1; i <= n; i ++) G[i].clear();
		for (int i = 1; i <= m; i ++) {
			int u, v, w;
			cin >> u >> v >> w;
			G[u].push_back({v, w});
		}
		cin >> k;
		for (int i = 1; i <= k; i ++) cin >> li[i];
		ll ans = 0x3f3f3f3f3f3f3f3f;
		for (int i = 0; i < 24; i ++) { // 枚举二进制位数
			ans = min(ans, dijkstra(i, 0));
			ans = min(ans, dijkstra(i, 1));
		}
		if(ans == 0x3f3f3f3f3f3f3f3f) cout << -1 << '\n';
		else cout << ans << '\n';
	}
	return 0;
}

标签:图论,进制,vis,int,二进制,分组,ans,P5304,dis
From: https://www.cnblogs.com/Ice-lift/p/17963431

相关文章

  • 图论 - 最短路随记
    顺序有点乱,后续会排一下,然后分板块整理All最短路算法的选择:\(n\le100\):Floyd(一般是较难的图论建模)\(n\le4\times10^5\):dijkstra尽量不用SPFA。神秘IDEA:一个带负权图,绝对最短路定义为,绝对值最小的最短路,求\(s\tot\)的绝对最短路。最短路中,任意......
  • 关于二进制的原码、补码和反码,以及表示范围、常见位运算符和进制转换的理解与简述
    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)https://www.cnblogs.com/cnb-yuchen/p/17963363出自【进步*于辰的博客】参考笔记一,P3.13、P5.1;笔记三,P43.1/3、P44.1。注:我暂且没有整理关于二进制、原码、补码和反码等概念的理论,本文中的阐述都基于我对相应......
  • 16进制转换为2进制的方法
    ///<summary>/////16转2方法///</summary>///<paramname="hexString"></param>///<returns></returns>staticstringHexString2BinString(stringhexString){......
  • 图论总结——最短路
    https://csacademy.com/app/graph_editor/https://riverhamster.gitee.io/app/graph_editor/注:时间复杂度分析中,假设\(n\lem\len^2\)。最短路本质上是一种DP。阶段:点状态:拆点决策:边最优子结构:最短路的任何子路径都一定是最短路。无后效性:正权图中一定可以找到一......
  • jdk jre 关键字 字面量 特殊字符 变量 进制
    JDK(JavaDevelopmentkit):Java开发工具包jvm:JavavirtualmachineJava虚拟机,Java真正运行的地方;核心类库:Java提前定义好的;开发工具:Javac编译工具,Java运行工具,jdb调试工具,jhat内存分析工具。JRE(JavaRuntimeEnvironment):Java运行环境  【把一些运行时用到的工具单独抽离......
  • 图论(2)
    目录130417130和昨天的飞地类似,都是从最边缘的位置进行dfs/bfs,然后判断哪个点没有被遍历过classSolution{public:intdir[4][2]={1,0,-1,0,0,1,0,-1};voiddfs(vector<vector<char>>&board,vector<vector<bool>>&visited,intx,inty){for(in......
  • 图论
    目录深搜入门leetcode797广搜入门leetcode200深搜和广搜6951020深搜入门leetcode797因为也是二刷,推的比较快刷题之后的感悟,其实就是先把模板写上去了之后再在里面缝缝补补出题目要求都比较模板,变通一下思路就能做出来classSolution{public:vector<vector<int>>resu......
  • python学习笔记7(不同进制之间的转换、算术运算符、赋值运算符、比较运算符、逻缉运算
    一)不同进制之间的转换二进制:0B或0b开头八进制:0o或0O开头十六进制:0x或0X开头(二)算术运算符//整除幂运算print(23)算术运算符优先级1、**2、*,/,%,//3、+,-(三)赋值运算符+=、-=、*=、/=、%=、**=、//=python支持链式赋值a=b=c=100python支持系列解包赋值a,b=10,20python中的值交换b,a=......
  • Kubernetes高可用集群二进制部署v1.28.0版本
    一、集群环境准备1.1主机规划        主机IP地址主机名主机配置主机角色软件列表192.168.198.144k8s-master12C4Gmasterkube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubectl192.168.198.145k8s-master22C4Gmasterkube-ap......
  • Python 字符串与十六进制字符串相互转换
    Python字符串与十六进制字符串相互转换在编程中,有时候我们需要将字符串与十六进制字符串之间进行转换。下面我们将展示如何使用Python实现这两个功能。1.将字符串转换为十六进制字符串我们可以创建一个函数ascii_to_hex_string来实现这个功能。该函数将输入的字符串转换为对......