Withthe increased use of pesticides, the local streams and rivers have become socontaminated that it has become almost impossible for the aquatic animals tosurvive.
Frog Fred is on the left bank of such a river. Nrocks are arranged in a straight line from the left bank to the right bank. Thedistance between the left and the right bank is D meters. There arerocks of two sizes. The bigger ones can withstand any weight but the smallerones start to drown as soon as any mass is placed on it. Fred has to go to theright bank where he has to collect a gift and return to the left bank where hishome is situated.
He can land on every small rock at most one time,but can use the bigger ones as many times as he likes. He can never touch thepolluted water as it is extremely contaminated.
Can you plan the itinerary so that the maximumdistance of a single leap is minimized?
Input
The first line of input is an integer T(T<100) that indicatesthe number of test cases. Each case starts with a line containing two integers N(0≤N≤100)and D(1≤D≤1000000000). The next line gives the descriptionof the N stones. Eachstone is defined by S-M. Sindicates the type Big(B) or Small(S)and M(0<M<D)determines the distance of that stone from the left bank. The stones will begiven in increasing order of M.
Output
For every case, output the case number followed by the minimized maximumleap.
Sample Input | Output for Sample Input |
3 1 10 B-5 1 10 S-5 2 10 B-3 S-6 | Case 1: 5 Case 2: 10 Case 3: 7 |
#include <cstdio>
#include <vector>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 220;
const int INF = 0x7f7f7f7f;
struct Edge
{
int from, to, cap, flow;
};
struct Rock
{
char kind;
int size;
};
Rock rock[N];
vector<Edge> edges;
vector<int> adjList[N];
int n, D;
int source, sink;
bool vis[N];
int d[N];
int cur[N];
void input();
int solve();
void addEdge(int u, int v, int c);
void clearAll(int n);
int maxflow();
bool bfs();
int dfs(int u, int a);
int main()
{
#ifndef ONLINE_JUDGE
freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++) {
input();
int ans = solve();
printf("Case %d: %d\n", i, ans);
}
return 0;
}
void input()
{
scanf("%d%d", &n, &D);
rock[0].kind = 'B', rock[0].size = 0;
rock[n + 1].kind = 'B', rock[n + 1].size = D;
for (int i = 1; i <= n; i++) {
scanf(" %c-%d", &rock[i].kind, &rock[i].size);
}
}
void addEdge(int u, int v, int c)
{
edges.push_back((Edge){u, v, c, 0});
edges.push_back((Edge){v, u, 0, 0});
int size = edges.size();
adjList[u].push_back(size - 2);
adjList[v].push_back(size - 1);
}
void clearAll(int n)
{
for (int i = 0; i < n; i++) adjList[i].clear();
edges.clear();
}
bool bfs()
{
memset(vis, false, sizeof(vis));
queue<int> q;
d[source] = 0;
q.push(source);
vis[source] = true;
while (!q.empty()) {
int u = q.front(); q.pop();
for (size_t i = 0; i < adjList[u].size(); i++) {
Edge edge = edges[adjList[u][i]];
int v = edge.to;
if (!vis[v] && edge.cap - edge.flow > 0) {
q.push(v);
d[v] = d[u] + 1;
vis[v] = true;
}
}
}
return vis[sink];
}
int dfs(int u, int a)
{
if (u == sink || a == 0) return a;
int flow = 0;
int f;
for (int& i = cur[u]; i < adjList[u].size(); i++) {
Edge &edge = edges[adjList[u][i]];
int v = edge.to;
if (d[v] == d[u] + 1 && (f = dfs(v, min(a, edge.cap - edge.flow))) > 0) {
edge.flow += f;
edges[adjList[u][i] ^ 1].flow -= f;
a -= f;
flow += f;
if (a == 0) break;
}
}
return flow;
}
int maxflow()
{
int ans = 0;
while (bfs()) {
memset(cur, 0x00, sizeof(cur));
ans += dfs(source, INF);
}
return ans;
}
int solve()
{
int l = 0, r = D;
int ans = D;
while (l <= r) {
int mid = (l + r) >> 1;
clearAll(2 * n + 4);
source = 0, sink = 2 * n + 3;
for (int i = 0; i <= n + 1; i++) {
if (rock[i].kind == 'B') {
addEdge(i, i + n + 2, INF);
} else {
addEdge(i, i + n + 2, 1);
}
for (int j = i + 1; j <= n + 1; j++) {
if (rock[j].size - rock[i].size <= mid) {
addEdge(i + n + 2, j, INF);
}
}
}
if (maxflow() >= 2) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
return ans;
}