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();
}