Travel in time
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 167 Accepted Submission(s): 36
Problem Description
Bob gets tired of playing games, leaves Alice, and travels to Changsha alone. Yuelu Mountain, Orange Island, Window of the World, the Provincial Museum etc...are scenic spots Bob wants to visit. However, his time is very limited, he can’t visit them all.
Assuming that there are N scenic spots in Changsha, Bob defines a satisfaction value Si to each spot. If he visits this spot, his total satisfaction value will plus Si. Bob hopes that within the limited time T, he can start at spot S, visit some spots selectively, and finally stop at spot E, so that the total satisfaction value can be as large as possible. It's obvious that visiting the spot will also cost some time, suppose that it takes C i units of time to visit spot i ( 0 <= i < N ).
Always remember, Bob can choose to pass by a spot without visiting it (including S and E), maybe he just want to walk shorter distance for saving time.
Bob also has a special need which is that he will only visit the spot whose satisfaction value is strictly larger than that of which he visited last time. For example, if he has visited a spot whose satisfaction value is 50, he would only visit spot whose satisfaction value is 51 or more then. The paths between the spots are bi-directional, of course.
Assuming that there are N scenic spots in Changsha, Bob defines a satisfaction value Si to each spot. If he visits this spot, his total satisfaction value will plus Si. Bob hopes that within the limited time T, he can start at spot S, visit some spots selectively, and finally stop at spot E, so that the total satisfaction value can be as large as possible. It's obvious that visiting the spot will also cost some time, suppose that it takes C i units of time to visit spot i ( 0 <= i < N ).
Always remember, Bob can choose to pass by a spot without visiting it (including S and E), maybe he just want to walk shorter distance for saving time.
Bob also has a special need which is that he will only visit the spot whose satisfaction value is strictly larger than that of which he visited last time. For example, if he has visited a spot whose satisfaction value is 50, he would only visit spot whose satisfaction value is 51 or more then. The paths between the spots are bi-directional, of course.
Input
The first line is an integer W, which is the number of testing cases, and the W sets of data are following.
The first line of each test data contains five integers: N M T S E. N represents the number of spots, 1 < N < 100; M represents the number of paths, 0 < M < 1000; T represents the time limitation, 0 < T <= 300; S means the spot Bob starts from. E indicates the end spot. (0 <= S, E < N)
The second line of the test data contains N integers C i ( 0 <= C i <= T ), which means the cost of time if Bob visits the spot i.
The third line also has N integers, which means the satisfaction value Si that can be obtained by visiting the spot i ( 0 <= S i < 100 ).
The next M lines, each line contains three integers u v L, means there is a bi-directional path between spot u and v and it takes L units of time to walk from u to v or from v to u. (0 <= u, v < N, 0 <= L <= T)
The first line of each test data contains five integers: N M T S E. N represents the number of spots, 1 < N < 100; M represents the number of paths, 0 < M < 1000; T represents the time limitation, 0 < T <= 300; S means the spot Bob starts from. E indicates the end spot. (0 <= S, E < N)
The second line of the test data contains N integers C i ( 0 <= C i <= T ), which means the cost of time if Bob visits the spot i.
The third line also has N integers, which means the satisfaction value Si that can be obtained by visiting the spot i ( 0 <= S i < 100 ).
The next M lines, each line contains three integers u v L, means there is a bi-directional path between spot u and v and it takes L units of time to walk from u to v or from v to u. (0 <= u, v < N, 0 <= L <= T)
Output
Output case number in the first line (formatted as the sample output).
The second line contains an integer, which is the greatest satisfaction value.
If Bob can’t reach spot E in T units of time, you should output just a “0” (without quotation marks).
The second line contains an integer, which is the greatest satisfaction value.
If Bob can’t reach spot E in T units of time, you should output just a “0” (without quotation marks).
Sample Input
1 4 4 22 0 3 1 1 1 1 5 7 9 12 0 1 10 1 3 10 0 2 10 2 3 10
Sample Output
Case #1: 21
Source
Recommend
zhoujiaqi2010
先用floyd预处理出两两之间的距离,建立有向图,边的方向从满意度低的点到满意度高的点。注意构造两个抽象的起点和终点,表示不访问该点而经过该点。
再跑一遍二维spfa,dist[i][j]表示在j时刻到达i点得到的最大满意度
最后在dist[终点][0~T]以及dist[抽象终点][0~T]中找最大值
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
#define MAXNODE 110
#define MAXTIME 721
#define MAXSATIS 100
#define oo (1<<29)
struct PATH
{
int v, L;
PATH(int _v, int _L){v = _v; L = _L;}
};
// Data of the graph
int N, M;
vector<struct PATH> Graph[MAXNODE];
// Start point, end point, time limit
int Sp, Ep, T;
// Satisfaction and time-cost of every sight spot
int s[MAXNODE], c[MAXNODE];
// Satisfaction[i][j] means the max satisfaction on Node i when time is j
int Satisfaction[MAXNODE][MAXTIME];
struct Node
{
int position, time;
Node(){}
Node(int _position, int _time)
{
position = _position;
time = _time;
}
};
queue<struct Node> que;
// whether the node is in the queue
bool InQueue[MAXNODE][MAXTIME];
Node Pop_Queue()
{
struct Node now = que.front();
que.pop();
InQueue[now.position][now.time] = false;
return now;
}
void Push_Queue(Node NewNode)
{
if (InQueue[NewNode.position][NewNode.time]) return;
que.push(NewNode);
InQueue[NewNode.position][NewNode.time] = true;
}
void SPFA()
{
// initialize
while (!que.empty()) que.pop();
for (int i = 0; i < N + 2; ++i)
for (int j = 0; j <= T; ++j)
{
Satisfaction[i][j] = 0;
InQueue[i][j] = false;
}
Push_Queue( Node(N, 0) );
Satisfaction[N][0] = 0;
while (!que.empty())
{
struct Node now = Pop_Queue();
// go to another spot - Relaxation operating
int size = Graph[now.position].size(), NewTime;
for (int i = 0; i < size; ++i)
{
int v = Graph[now.position][i].v;
NewTime = now.time + Graph[now.position][i].L;
if (NewTime > T) continue;
if (Satisfaction[now.position][now.time] + s[v] > Satisfaction[v][NewTime])
{
Satisfaction[v][NewTime] = Satisfaction[now.position][now.time] + s[v];
Push_Queue( Node(v, NewTime) );
}
}
}
}
int Matrix[MAXNODE][MAXNODE];
// Read data
void Init()
{
scanf("%d %d %d %d %d", &N, &M, &T, &Sp, &Ep);
for (int i = 0; i < N; ++i) scanf("%d", &c[i]);
for (int i = 0; i < N; ++i) scanf("%d", &s[i]);
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
Matrix[i][j] = (i == j)? (0) : (oo);
while (M--)
{
int u, v, l;
scanf("%d %d %d", &u, &v, &l);
Matrix[u][v] = Matrix[v][u] = min(Matrix[u][v], l);
}
}
void Floyd_Warshall()
{
for (int k = 0; k < N; ++k)
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
Matrix[i][j] = min(Matrix[i][j], Matrix[i][k] + Matrix[k][j]);
}
void Add_Edge(int from, int to, int cost)
{
Graph[from].push_back(PATH(to, cost));
}
void Build_Graph()
{
s[N + 1] = 0;
for (int i = 0; i < N + 2; ++i) Graph[i].clear();
for (int i = 0; i < N; ++i)
for (int j = i + 1; j < N; ++j)
if (Matrix[i][j] < oo)
{
if (s[i] > s[j]) Add_Edge(j, i, Matrix[i][j] + c[i]);
else if (s[i] < s[j]) Add_Edge(i, j, Matrix[i][j] + c[j]);
}
//Super source - N
for (int i = 0; i < N; ++i)
if (i != Sp && Matrix[Sp][i] < oo)
Add_Edge(N, i, Matrix[Sp][i] + c[i]);
Add_Edge(N, Sp, c[Sp]);
//Super dest - N + 1
for (int i = 0; i < N; ++i)
if (i != Ep && Matrix[i][Ep] < oo)
Add_Edge(i, N + 1, Matrix[i][Ep]);
}
int main()
{
//freopen("Travel_in_Time.in", "r", stdin);
//freopen("testTravel_in_Time.out", "w", stdout);
int Case;
scanf("%d", &Case);
for (int i = 1; i <= Case; ++i)
{
Init();
Floyd_Warshall();
Build_Graph();
SPFA();
int maxS = 0;
for (int t = 0; t <= T; ++t)
{
maxS = max (maxS, Satisfaction[N + 1][t]);
maxS = max (maxS, Satisfaction[Ep][t]);
}
printf("Case #%d:\n%d\n", i, maxS);
}
return 0;
}