首页 > 其他分享 >abc369E Sightseeing Tour

abc369E Sightseeing Tour

时间:2024-10-07 18:44:34浏览次数:9  
标签:std int 座桥 i64 耗时 Tour edges abc369E Sightseeing

有N个岛和M座双向桥,编号为i的桥连接岛U[i]和V[i],过桥耗时T[i],桥连接两不同的岛屿,两个岛之间可能会有多座桥。
有Q组询问,每次询问给出K座桥,问从1号岛到N号岛的最少耗时,要求给出的K座桥分别至少经过1次。
2<=N<=400; N-1<=M<=2E5; 1<=U[i]<V[i]<=N; 1<=T[i]<=1E9; 1<=Q<=3000; 1<=K[i]<=5;

分析:跑floyd求出任意两岛之间的最短耗时,然后枚举所有可能的路径,即对K座桥全排列,并枚举桥的两端谁做入口谁做出口,将"1-桥-N"串起来得到耗时,取最小值。

#include <bits/stdc++.h>
using i64 = long long;

const i64 inf = 1E18;
i64 d[405][405];

void solve() {
	int N, M;
	std::cin >> N >> M;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			if (i == j) {
				d[i][j] = 0;
			} else {
				d[i][j] = inf;
			}
		}
	}

	std::vector<std::tuple<int,int,int>> edges(M+1);
	for (int i = 1; i <= M; i++) {
		int u, v;
		i64 t;
		std::cin >> u >> v >> t;
		edges[i] = {u, v, t};
		d[u][v] = std::min(d[u][v], t);
		d[v][u] = std::min(d[v][u], t);
	}

	for (int k = 1; k <= N; k++) {
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++) {
				d[i][j] = std::min(d[i][j], d[i][k] + d[k][j]);
			}
		}
	}

	auto getb = [&](const std::vector<int> &v, int st, i64 &w) {
		std::vector<int> res;
		for (size_t i = 0; i < v.size(); i++) {
			int x, y, z;
			std::tie(x, y, z) = edges[v[i]];
			if (st & (1 << i)) {
				res.push_back(y);
				res.push_back(x);
			} else {
				res.push_back(x);
				res.push_back(y);
			}
			w += z;
		}
		return res;
	};

	int Q;
	std::cin >> Q;
	for (int i = 1; i <= Q; i++) {
		int K;
		std::cin >> K;
		std::vector<int> B(K);
		for (auto &x : B) {
			std::cin >> x;
		}
		std::sort(B.begin(), B.end());

		i64 ans = inf;
		do {
			for (int j = 0; j < (1 << K); j++) {
				i64 res = 0;
				auto b = getb(B, j, res);
				res += d[1][b.front()] + d[b.back()][N];
				for (size_t k = 2; k < b.size(); k += 2) {
					res += d[b[k]][b[k-1]];
				}
				ans = std::min(ans, res);
			}
		} while (std::next_permutation(B.begin(), B.end()));
		std::cout << ans << "\n";
	}
}

int main() {
	std::cin.tie(0)->sync_with_stdio(0);
	int t = 1;
	while (t--) solve();
	return 0;
}

标签:std,int,座桥,i64,耗时,Tour,edges,abc369E,Sightseeing
From: https://www.cnblogs.com/chenfy27/p/18450411

相关文章

  • 【Tourism】Luoyang(1)
    文章目录洛阳1、龙门石窟(AAAAA)2、白马寺(AAAA)洛阳洛阳市,简称“洛”,古称成周、神都、洛邑、洛京,是河南省辖地级市、世界文化名城、首批国家历史文化名城、国家区域性中心城市、中原城市群副中心城市、“一带一路”重要节点城市,三线城市,国务院批复确定的河南省副中心城......
  • CF589H Tourist Guide
    昨晚码敲完了没保存,导致还原卡直接把我码肘没了。。。气死了只能重新敲了一遍。题面TouristGuide分析考虑每一个联通块分开处理。先将每一个联通块变为生成树,任意生成方式皆可。对于每一个联通块,一定可以构造一种组合方法,使得该联通块中最多只有一个关键点无法被选择。并......
  • SP1825 FTOUR2 - Free tour II 题解
    题目传送门前置知识点分治|树状数组解法维护点对信息,考虑点分治。本题比luoguP4149[IOI2011]Race多了个前缀查询\(\max\)。套个支持单点修改、区间查询\(\max\)的数据结构即可。直接线段树维护区间\(\max\)貌似会TLE,换成树状数组维护前缀\(\max\)即可。注......
  • [POI2014] TUR-Tourism
    [POI2014]TUR-Tourism题意给出一张图,在这张图中,任意两点间不存在节点数超过\(10\)的简单路径。第\(i\)个点被选的代价为\(C_i\),每个节点要么选,要么与它直接相连的点中至少有一个被选。求最小代价。思路图的生成树上状压动态规划。由于给出的是一张图,无法直接dp,我们可......
  • OpenCV(cv::drawContours())
    目录1.函数原型2.示例1.函数原型cv::drawContours()用于在图像上绘制轮廓。函数原型:voidcv::drawContours(cv::InputOutputArrayimage,conststd::vector<std::vector<cv::Point>>&contours,intcontourIdx,constc......
  • OpenCV结构分析与形状描述符(17)判断轮廓是否为凸多边形的函数isContourConvex()的使用
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述测试轮廓的凸性。该函数测试输入的轮廓是否为凸的。轮廓必须是简单的,即没有自相交。否则,函数的输出是不确定的。cv::isContourConvex函数是OpenCV提供的一个用于判断轮廓是否......
  • 题解:[USACO07DEC] Sightseeing Cows G
    洛谷P2868题目大意有个nnn个点,mmm条边的有向图,点有点权,边有边......
  • [luoguAT_abc369_e] Sight[luoguAT_abc369_e]Sightseeing Tour
    题意给定一个包含\(N\)个点和\(M\)条无向边的带权图,保证图中没有自环,但可能包含重边。给出\(Q\)次查询,每次查询给出\(K\)条边\(B_1,B_2,\cdots,B_K\),要求求出从节点\(1\)到节点\(N\)且这\(K\)条边都至少经过一次的最短路(经过边的方向和顺序任意)。赛时Dijkstra......
  • 题解:AT_abc369_e [ABC369E] Sightseeing Tour 详细版
    题目大意给定一个NNN个点,MMM条边的无向图。其中边有边权。有......
  • OpenCV(cv::findContours())
    目录1.函数定义2.示例3.常见应用4.注意事项cv::findContours()是OpenCV中用于检测图像中的轮廓的函数。1.函数定义voidfindContours(InputOutputArrayimage,OutputArrayOfArrayscontours,OutputArrayhierarchy,intmode,intmethod......