HackerRank - synchronous-shopping(二维最短路)

2019.6.12 今天突然发现这个OJ复活了(之前一段时间一直连不上).然后发现好像这道题目的题面已经完全不一样了,特地去交了一发,代码仍然是可以通过的,不打算更新题面了,应该解决的问题还是那个问题,只不过换了一种表达方式。

 

Bitville is a seaside city that has  shopping centers connected via bidirectional roads. Each road connects exactly two distinct shopping centers and has a travel time associated with it.

There are  different types of fish sold in Bitville. Historically, any shopping center has a fishmonger selling certain types of fish. Buying any amount of fish from any fishmonger takes no time.

Our heroes, Big Cat and Little Cat, are standing at Bitville shopping center number . They have a list of the types of fish sold at each fishmonger, and they want to collectively purchase all  types of fish in a minimal amount of time. To do this, they decide to split the shopping between themselves in the following way:

  • Both cats choose their own paths, starting at shopping center  and ending at shopping center . It should be noted that Little Cat's path is not necessarily the same as Big Cat's.
  • While traveling their respective paths, each cat will buy certain types of fish at certain shops.
  • When the cats reach shopping center , they must have collectively purchased all  types of fish in a minimal amount of time.
  • If one cat finishes shopping before the other, he waits at shopping center for his partner to finish; this means that the total shopping time is the maximum of Little and Big Cats' respective shopping times.

It is to be noted that any of the cats can visit the shopping center  in between, but they both have to finish their paths at the shopping center .

Given the layout for Bitville and the list of fish types sold at each fishmonger, what is the minimum amount of time it will take for Big and Little Cat to purchase all  types of fish and meet up at shopping center ?

Input Format

The first line contains  space-separated integers:  (the number of shopping centers),  (the number of roads), and  (the number of types of fish sold in Bitville), respectively.

Each line  of the  subsequent lines () describes a shopping center as a line of space-separated integers. Each line takes the following form:

  • The first integer, , denotes the number of types of fish that are sold by the fishmonger at the  shopping center.
  • Each of the  subsequent integers on the line describes a type of fish sold by that fishmonger. Which is denoted by .

Each line  of the  subsequent lines () contains  space-separated integers describing a road. The first two integers,  and , describe the two shopping centers it connects. The third integer, , denotes the amount of time it takes to travel the road (i.e., travel time).

Constraints

  •  
  •  
  •  
  •  
  •  
  • All  are different for every fixed .
  •  
  •  
  • Each road connectes  distinct shopping centers (i.e., no road connects a shopping center to itself).
  • Each pair of shopping centers is directly connected by no more than  road.
  • It is possible to get to any shopping center from any other shopping center.
  • Each type of fish is always sold by at least one fishmonger.

Output Format

Print the minimum amount of time it will take for the cats to collectively purchase all  fish and meet up at shopping center .

Sample Input

5 5 5
1 1
1 2
1 3
1 4
1 5
1 2 10
1 3 10
2 4 10
3 5 10
4 5 10

Sample Output

30

Explanation

Big Cat can choose the following route: , and buy fish at all of the shopping centers on his way.

Little Cat can choose the following route: , and buy fish from the fishmonger at the  shopping center only.

 

 

一、原题地址

点我传送

 

二、大致题意

现有 n 个城市,m 条路,k个商品需要被购买。有两个人同时出发去买商品。

在接下来的 n 行将会给出每个城市所拥有的商品。再给出 m 条相连的路。

询问在到达第 n 个城市并且买齐所有商品所需要花费的最大时间(两个人买东西,取时间较长的人)的最小值是多少。

 

三、大致思路

和最短路一样,用二维的 dis[ i ][ state ]记录到达第 i 个城市,购买状态为state时的最小花费。用二维vis[ ][ ]记录更新情况。购买状态用01串的形式来表现就行。这里用的是堆优化的迪杰斯特拉。最后n^2枚举两个人的状态,若满足了所有商品,就更新答案。

 

四、代码

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<set>
#include<map>
#include<unordered_set>
#include<vector>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long LL;
const double eps = 1e-6;



typedef struct
{
	int v, next, cost;
}Edge;
typedef struct
{
	int v, cost,state;
}Node;
bool operator <(const Node &a, const Node &b)
{
	return a.cost>b.cost;
}

int n, m, K;
int needstate;
const int MAXN = 1005, MAXM = 4005;
int head[MAXM], fish[MAXN];
bool vis[MAXN][(1 << 11)];
int dis[MAXN][(1 << 11)];
Edge e[MAXM];
int ind;
void add(int from, int to, int cost)
{
	e[ind].next = head[from];
	e[ind].v = to;
	e[ind].cost = cost;
	head[from] = ind++;
}

void init()
{
	ind = 0;
	memset(head, -1, sizeof(head));
	memset(fish, 0, sizeof(fish));
	needstate = (1 << K) - 1;
}

void read()
{
	for (int i = 1; i <= n; i++)
	{
		int T;
		scanf("%d", &T);
		while (T--)
		{
			int type;
			scanf("%d", &type);
			fish[i] |= (1 << (type - 1));
		}
	}
	for (int i = 1; i <= m; i++)
	{
		int u, v, w;
		scanf("%d %d %d", &u, &v, &w);
		add(u, v, w);
		add(v, u, w);
	}
}

void Dij(int start,int end)
{
	memset(vis, false, sizeof(vis));
	memset(dis, inf, sizeof(dis));
	Node t;
	priority_queue<Node>q;
	t.cost = 0;
	dis[start][fish[start]] = 0;
	t.v = start;
	t.state = fish[start];
	q.push(t);
	while (!q.empty())
	{
		t = q.top();
		q.pop();
		if (vis[t.v][t.state])continue;
		vis[t.v][t.state] = true;
		for (int i = head[t.v]; i != -1; i = e[i].next)
		{
			int to = e[i].v;
			int nextstate = t.state | fish[to];
			if (!vis[to][nextstate] && dis[to][nextstate] > dis[t.v][t.state] + e[i].cost)
			{
				Node nex;
				nex.v = to;
				nex.state = t.state | fish[to];
				nex.cost = e[i].cost + t.cost;
				dis[nex.v][nex.state] = nex.cost;
				q.push(nex);
			}
		}
	}
	return;
}

void Mainwork()
{
	Dij(1, n);
	int ans = inf;
	for (int i = fish[1]; i <= (1 << K) - 1; i++)
	{
		for (int j = fish[1]; j <= (1 << K) - 1; j++)
		{
			if ((i | j) == needstate)
			{
				//printf("%d\n", max(dis[n][i], dis[n][j]));
				ans = min(ans, max(dis[n][i], dis[n][j]));
			}
		}
	}
	printf("%d\n", ans);
}

int main()
{
	while (scanf("%d %d %d", &n, &m, &K) != EOF)
	{
		init();
		read();
		Mainwork();
	}
	getchar();
	getchar();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值