列表

详情


NC223575. DragonBallII

描述

There used to be a legendary tale about Dragon Balls on Planet X: if one collects seven Dragon Balls, the Dragon God will show up and help you fulfill your wishes.

 However, ever since a Dragon Ball radar was discovered, which pinpoints the location of each Dragon Ball, collecting all seven balls has become too easy, to the point that the Dragon God is pestered non-stop by frivolous wishes. He has had enough, and so wants to make the process of collecting the balls harder. Instead of seven balls, he has created a huge number, each with a (not necessarily distinct) serial number. To summon the Dragon God, you now need to collect seven Dragon Balls with pairwise distinct serial numbers: duplicate Balls do not help you. 

You recently bought a Dragon Ball radar at a flea market, which tells you which city each Dragon Ball resides in, as well as that ball’s serial number. Can you still find the cheapest way to summon the Dragon God? 

There are n cities in total on the Planet X, numbered from 1 to n. You are currently at city 1. To travel from one city to another, you can take any of m bidirectional teleport trips, as many times as you like. The i-th teleporter costs ti coins to use each time, and it can teleport you between cities a_i and b_i . To collect a Dragon Ball, you simply need to visit the city where it’s located, as indicated on your radar. It is possible that multiple Dragon Balls are at the same city; in this case you pick all of them all up at once if you visit that city.

输入描述

The first line of input contains three space-separated integers n, m, and k (1 ≤ n, k ≤ 1 000, 1 ≤ m ≤ 10 000), thenumber of cities, teleport trips, and Dragon Balls, respectively. Then follow m lines containing three space-separatedintegers ai , bi , and ti each (1 ≤ ai , bi ≤ n, 0 ≤ ti ≤ 10 000), which, as explained above, represent the two citiesconnected by the teleport trip, and cost to use the teleporter.Then follow k lines, the i-th of which contains two space-separated integers ci and di (1 ≤ ci , di ≤ n), indicatingthat the i-th Dragon Ball is located in city ci and has serial number di . Note that there might be multiple Dragon Ballslocated in the same city, multiple Dragon Balls that share the same serial number, or even multiple Dragon Balls withthe same serial number in the same city.

输出描述

Print the minimum number of coins that you have to spend to collect seven Dragon Balls with pairwise distinct serial number. If there is no way to complete this task, print −1.

示例1

输入:

11 10 10
1 2 1
2 3 1
3 4 1
1 5 1
5 6 1
6 7 1
7 8 1
1 9 1
1 10 1
1 11 1
2 1
3 2
4 3
5 1
6 2
7 3
8 4
9 5
10 6
11 7

输出:

10

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 1611ms, 内存消耗: 16168K, 提交时间: 2021-08-19 16:38:48

#include <cstdio>
#include <queue>
#include <vector>
#include <random>
#include <algorithm>
#define pb push_back
#define INF 0x3f3f3f3f
using std::queue;
using std::vector;
const int N=200005;
std::mt19937 rnd(114);
int n, m, k, p[8], T=800;
int ans, cur;
vector<int> e[N], w[N], id[N];
int rid[8];
int q[N<<5], *ql, *qr;
//queue<int> q;
int in[N], ok[N][8];
int dis[1<<7][N], *rdis;
inline void ins(int u)
{
	if(rdis[u]<rdis[*ql]) *(--ql)=u;
	else *(++qr)=u;
}
void dij(int *dis)
{
	std::fill(in+1, in+n+1, 1);
	rdis=dis;
	ql=q+16*n, qr=ql-1;
	for(int i=1; i<=n; ++i) ins(i);
	while(ql<=qr)
	{
		int u=*(ql++);
		in[u]=0;
		if(dis[u]>=ans) continue;
		for(int i=0; i<e[u].size(); ++i)
		{
			int v=e[u][i], c=w[u][i];
			if(dis[v]>dis[u]+c)
			{
				dis[v]=dis[u]+c;
				if(!in[v]) ins(v);
			}
		}
	}
}
void solve(void)
{
	std::iota(p, p+8, 0);
	for(int i=1; i<=7; ++i) rid[i]=0;
	for(int i=1; i<=n; ++i) std::fill(ok[i], ok[i]+8, 0);
	for(int i=1; i<=n; ++i)
	{
		int t=rnd()%7;
		rid[t]=1;
//		t=i-1;
		for(int x:id[i]) ok[x][t]=1;
	}
//	for(int i=0; i<7; ++i) if(!rid[i]) return;
	for(int s=0; s<(1<<7); ++s) std::fill(dis[s], dis[s]+n+1, INF);
	dis[0][1]=0;
	for(int s=0; s<(1<<7); ++s)
	{
		for(int u=1; u<=n; ++u) for(int i=0; i<7; ++i) if((s&(1<<i))&&ok[u][i])
		{
			dis[s][u]=std::min(dis[s][u], dis[s^(1<<i)][u]);
		}
		dij(dis[s]);
	}
	for(int i=1; i<=n; ++i) ans=std::min(ans, dis[(1<<7)-1][i]);
}
int main()
{
	scanf("%d%d%d", &n, &m, &k);
	for(int i=1, x, y, z; i<=m; ++i) scanf("%d%d%d", &x, &y, &z), e[x].pb(y), w[x].pb(z), e[y].pb(x), w[y].pb(z);
	for(int i=1, c, d; i<=k; ++i) scanf("%d%d", &c, &d), id[d].pb(c);
	ans=INF;
	while(T--) solve();
	printf("%d\n", ans==INF?-1:ans);
	return 0;
}

上一题