蓝桥杯-景区导游-DFS

某景区一共有 N 个景点,编号 1 到 N。景点之间共有 N − 1 条双向的摆渡车线路相连,形成一棵树状结构。在景点之间往返只能通过这些摆渡车进行,需要花费一定的时间。

小明是这个景区的资深导游,他每天都要按固定顺序带客人游览其中 K 个景点:A1, A2, . . . , AK。今天由于时间原因,小明决定跳过其中一个景点,只带游客按顺序游览其中 K − 1 个景点。具体来说,如果小明选择跳过 Ai,那么他会按顺序带游客游览 A1, A2, . . . , Ai−1, Ai+1, . . . , AK, (1 ≤ i ≤ K)。

请你对任意一个 Ai,计算如果跳过这个景点,小明需要花费多少时间在景点之间的摆渡车上?

输入格式

第一行包含 2 个整数 N 和 K。

以下 N − 1 行,每行包含 3 个整数 u, v 和 t,代表景点 u 和 v 之间有摆渡车线路,花费 t 个单位时间。

最后一行包含 K 个整数 A1, A2, . . . , AK 代表原定游览线路。

输出格式

输出 K 个整数,其中第 i 个代表跳过 Ai 之后,花费在摆渡车上的时间。

样例输入

复制

6 4
1 2 1
1 3 1
3 4 2
3 5 2
4 6 3
2 6 5 1

样例输出

复制

10 7 13 14

提示

原路线是 2 → 6 → 5 → 1。

当跳过 2 时,路线是 6 → 5 → 1,其中 6 → 5 花费时间 3 + 2 + 2 = 7,5 → 1 花费时间 2 + 1 = 3,总时间花费 10。

当跳过 6 时,路线是 2 → 5 → 1,其中 2 → 5 花费时间 1 + 1 + 2 = 4,5 → 1 花费时间 2 + 1 = 3,总时间花费 7。

当跳过 5 时,路线是 2 → 6 → 1,其中 2 → 6 花费时间 1 + 1 + 2 + 3 = 7,6 → 1 花费时间 3 + 2 + 1 = 6,总时间花费 13。

当跳过 1 时,路线时 2 → 6 → 5,其中 2 → 6 花费时间 1 + 1 + 2 + 3 = 7,6 → 5 花费时间 3 + 2 + 2 = 7,总时间花费 14。

对于 20% 的数据,2 ≤ K ≤ N ≤ 102。

对于 40% 的数据,2 ≤ K ≤ N ≤ 104。

对于 100% 的数据,2 ≤ K ≤ N ≤ 105,1 ≤ u, v, Ai ≤ N,1 ≤ t ≤ 105。保证Ai 两两不同。

#include 
#include
#include
using namespace std;
#define INF 0x3f3f3f
#define int long long
#define deb(x)cout<<#x<<"="<pii;
mapst;               //key是起点和终点,value是距离
int a[N];                      //节点的顺序,即要游览的景点顺序

vectore[N];            //key是当前节点,value是终点和距离

bool dfs(int s,int u,int v,int father,int sum)
{
	if (u == v)
	{
		st[{v, s}]=st[{s, v}] = sum;
		return true;
	}
	for (int i = 0; i < e[u].size(); i++) //循环找到当前节点的没有经过的节点
	{
		int son = e[u][i].first;
		if ( son== father) continue;
		sum += e[u][i].second;
		if(dfs(s, son, v, u, sum))return true;
	}
	return false;
}

void solve()
{
	int n, k;
	cin >> n >> k;
	for (int i = 0; i < n-1; i++)
	{
		int x, y, t;
		cin >> x >> y >> t;
		e[x].push_back({ y,t });                    //输入一个游览图
		e[y].push_back({ x,t });
	}
	for (int i = 0; i < k; i++)
	{
		cin >> a[i];             //输入k个要又游览的景点
	}

	int ans = 0;                 //计算需要游览的景点的距离
	for (int i = 0; i < k; i++)
	{
		dfs(a[i], a[i], a[i + 1], -1, 0);
		ans += st[{a[i], a[i + 1]}];
	}
	for (int i = 0; i < k; i++)
	{
		int temp;
		if (i == 0)
		{
			temp = ans - st[{a[i], a[i + 1]}];
		}
		else if (i == k - 1)
		{
			temp = ans - st[{a[i-1], a[i]}];
		}
		else
		{		
			dfs(a[i - 1], a[i - 1], a[i + 1], -1, 0);
			temp = ans - st[{a[i], a[i + 1]}] - st[{a[i - 1], a[i]}] + st[{a[i - 1], a[i + 1]}];

		}
		cout << temp << endl;
	}
}
signed main()
{
	ios::sync_with_stdio;
	cin.tie(0);
	cout.tie(0);
	int num = 1;
	while (num--)
	{
		solve();
	}
}

你可能感兴趣的:(c++,蓝桥杯,算法)