首页 > 其他分享 >题解:AT_abc369_e [ABC369E] Sightseeing Tour 详细版

题解:AT_abc369_e [ABC369E] Sightseeing Tour 详细版

时间:2024-09-06 21:54:43浏览次数:7  
标签:int 题解 短路 abc369 vis Tour 810 include dis

题目大意

给定一个 N N N 个点, M M M 条边的无向图。其中边有边权。有 Q Q Q 次询问,每一次给你 K K K 条必须经过的边(但是方向没有限制),问从 1 1 1 到 N N N 的最短路长度是多少。

思路

观察数据范围,可以发现:虽然 M M M 很大,但是 N N N 和 K K K 并不大。 K ≤ 5 K\le5 K≤5,可以暴力枚举每一条边经过时的方向以及经过它们的顺序。 N ≤ 400 N\le400 N≤400,考虑预处理出任意两点之间的最短路。

我们使用dfs来暴力枚举,首先考虑每条边的方向,再全排列去确定遍历顺序。在每一种具体方案中,我们可以将点之间的最短路相加,并且加上边权,得出这种方案的最短路径长度,再取最小值即可。

代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
typedef long long LL;

int n, m, q, k;
int a[40], b[40];
LL ans; // 答案
int A[400010]; // 边
int B[400010]; // 边
int C[400010]; // 边
LL dis[810][810]; // 最短路
int vis[810][810]; // 标记

struct edge // 边
{
	int y, w;
} ;

vector<edge> g[810]; // 图

void add(int x, int y, int w) // 建边
{
	g[x].push_back((edge){y, w});
}

struct node // 点
{
	int x; // 编号
	LL d; // 距离起点的最短路
	
	bool operator < (const node & b) const // 重载运算符
	{
		return d > b.d;
	}
} ;

void dijkstra(int s) // 最短路
{
	priority_queue<node> q;
	memset(dis[s], 0x3f, sizeof(dis[s]));
	memset(vis[s], 0, sizeof(vis[s]));
	q.push((node){s, 0});
	dis[s][s] = 0;
	while (q.size())
	{
		int x = q.top().x;
		q.pop();
		if (vis[s][x])
			continue;
		vis[s][x] = 1;
		for (int i = 0; i < g[x].size(); i++)
		{
			int y = g[x][i].y;
			int w = g[x][i].w;
			if (dis[s][y] > dis[s][x] + w)
			{
				dis[s][y] = dis[s][x] + w;
				q.push((node){y, dis[s][y]});
			}
		}
	}
}

void solve(int step) // 暴力枚举
{
	if (step > k)
	{
		for (int i = 1; i <= k; i++)
			b[i] = i;
		do
		{
			LL sum = dis[1][A[a[b[1]]]];
			for (int i = 2; i <= k; i++)
				sum += C[a[b[i - 1]]] + dis[B[a[b[i - 1]]]][A[a[b[i]]]];
			sum += C[a[b[k]]] + dis[B[a[b[k]]]][n];
			ans = min(ans, sum);
		} while (next_permutation(b + 1, b + k + 1)); // 全排列
		return ;
	}
	swap(A[a[step]], B[a[step]]); // 边的方向
	solve(step + 1);
	swap(A[a[step]], B[a[step]]); // 边的方向
	solve(step + 1);
}

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		int x, y, w;
		cin >> x >> y >> w;
		add(x, y, w);
		add(y, x, w);
		A[i] = x;
		B[i] = y;
		C[i] = w;
	}
	for (int i = 1; i <= n; i++)
		dijkstra(i);
	cin >> q;
	while (q--)
	{
		cin >> k;
		for (int i = 1; i <= k; i++)
			cin >> a[i];
		ans = 9e18; // 不要忘记初始值
		solve(1);
		cout << ans << endl;
	}
	return 0;
} 

标签:int,题解,短路,abc369,vis,Tour,810,include,dis
From: https://blog.csdn.net/ArmeriaLeap/article/details/141939332

相关文章

  • MySQL 日期函数语法介绍和案例示范以及常见问题解决
    本文将以电商交易系统为例,详细讲解MySQL日期类型及其转化,常用的日期函数,以及一些解决常见问题的方案。一、MySQL日期数据类型MySQL提供了多种日期数据类型,适用于不同的使用场景。常见的日期类型包括DATE、DATETIME、TIMESTAMP、TIME和YEAR。DATE:只存储日期,不包含......
  • 题解:SP3693 KGSS - Maximum Sum
    原题传送门思路分析线段树。这道题让我们进行两种操作,分别是单点修改和区间查询,结合数据范围,很明显是一道线段树。区间里最大的\(A_i+A_j\),其实就是求区间里的最大值和次大值,我们用线段树维护最大值和次大值。建树voidbuild(intnow,inttl,inttr){ if(tl==tr){ tmax......
  • P6638 「JYLOI Round 1」常规 题解
    题目传送门前置知识可持久化线段树|前缀和&差分解法进行差分,区间查询转化成前缀和相减。先将\(\{a\}\)升序排序。设当前询问的区间为\([1,r]\),在\(\{a\}\)中找到一个最大的\(pos\)使得\(a_{pos}\ler\),则\([1,r]\)中所做常规的次数为\(\sum\limits_{i=1......
  • 使用flask进行Mock Server模拟接口操作及问题解决
    1.flask介绍flask是一个轻量级的pythonweb微框架2.MockServer介绍MockServer是一个开源的模拟服务器,它可以定义和记录API交互,支持各种http方法(get、post、put、delete),可以自定义响应内容,例如返回静态文件可以使用flask来搭建一个mock模拟服务3.模拟接口先安装flaskpip......
  • P1928 外星密码题解
    初看这题时,感觉就是一个简简单单的递归,便有了以下代码:#include <bits/stdc++.h>using namespace std;string re(){    string s="",s1="";    char c;    int n;    while(cin>>c){        if(c=='['){            cin>>n;......
  • AT_keyence2019_e Connecting Cities 题解
    B算法萌萌题。题解看到完全图求最小生成树,必然是要考虑一下B算法能不能做的。发现这个题的联通块最小值是可以维护的。我们发现。假如我们钦定\(i\)往前面连。那么前面的最小权值必然是一个固定的值。我们一定会连到\(\min(a_j-j\timesD)\)上。由于不能连到自己......
  • AT_aising2019_e Attack to a Tree 题解
    挺有意思的树型dp。思路发现直接求解很难对限制下手。但我们可以注意到答案最多为\(n\)。考虑将答案记录dp状态。我们可以记\(dp_{i,j}\)为子树\(i\)合法并且断了\(j\)条边的状态。由于合法状态有两种,并且不好一起考虑,所以可以再在dp状态中加一维。令\(dp_{i,......
  • P8139 [ICPC2020 WF] Sweep Stakes 题解
    思路容易发现,题目要求我们动态维护这样一个多项式。\[\prod_{i}(1-p_i+p_ix)\]如何维护。由于精度问题,我们很难去进行一个多项式除法将其暴力求出。考虑\(p_i\le0.2\)。可以得知,我们的多项式的数的增减是比较大的。那么在一定数量后,一些可能有值的系数在当前精度下是可以......
  • ORCLE数据库语言设置原因查询不出数据的问题解决
    问题现象:oracle数据库视图中存在数据,但是jdbc查询视图查询不出来,后发现视图中有根据默认语言的过滤,如下图: 客户端查询环境语言为 web服务器查询环境语言为US,所以数据查询不出来。解决方案:修改应用端的NLS_LANG的配置与SQL保持一致linux执行下面代码exportNLS_LANG="......
  • CF1469D Ceil Divisions题解
    CF1469DCeilDivisions感觉是很巧妙的一题?一开始想到,对于任何小于$n$的数$x$,直接对它除以$n$可以得到$1$。那么对$3\simn-1$做完此操作后,还剩下$1$、$2$、$n$。将$n$变成$1$要花费$logn$次,显然总操作次数超过了$n+5$次。进一步地,发现瓶颈在于把$n$变成$1$,于是利用根号,用$\sqr......