|
With the increased use of pesticides, the local streams and rivers have become so contaminated that it has become almost impossible for the aquatic animals to survive.
Frog Fred is on the left bank of such a river. N rocks are arranged in a straight line from the left bank to the right bank. The distance between the left and the right bank is D meters. There are rocks of two sizes. The bigger ones can withstand any weight but the smaller ones start to drown as soon as any mass is placed on it. Fred has to go to the right bank where he has to collect a gift and return to the left bank where his home 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 the polluted water as it is extremely contaminated.
Can you plan the itinerary so that the maximum distance of a single leap is minimized?
Input
The first line of input is an integer T(T<100) that indicates the number of test cases. Each case starts with a line containing two integersN(0≤N≤100)and D(1≤D≤1000000000). The next line gives the description of the N stones. Each stone 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 be given in increasing order of M.
Output
For every case, output the case number followed by the minimized maximum leap.
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 |
Problem Setter: Sohel Hafiz
Special Thanks: Jane Alam Jan
这题貌似有很多种做法,dp,贪心,贪心我不知道该怎么证明,然后看n只有100,,写了个最大流过了。貌似出题人的标程也是用最大流写的。
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <stack>
#include <set>
#include <cstring>
#include <stdlib.h>
#include <cmath>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 200 + 5;
const int INF = 1000000000;
struct Edge {
int from, to, cap, flow;
};
struct Dinic {
int n, m, s, t;
vector<Edge> edges; // 边数的两倍
vector<int> G[maxn]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
bool vis[maxn]; // BFS使用
int d[maxn]; // 从起点到i的距离
int cur[maxn]; // 当前弧指针
void ClearAll(int n) {
for(int i = 0; i < n; i++) G[i].clear();
edges.clear();
}
void ClearFlow() {
for(int i = 0; i < edges.size(); i++) edges[i].flow = 0;
}
void AddEdge(int from, int to, int cap) {
//cout << from << ' ' << to << ' ' << cap << endl;
edges.push_back((Edge){from, to, cap, 0});
edges.push_back((Edge){to, from, 0, 0});
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BFS() {
memset(vis, 0, sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = 1;
d[s] = 0;
while(!Q.empty()) {
int x = Q.front(); Q.pop();
for(int i = 0; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow) {
vis[e.to] = 1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x, int a) {
if(x == t || a == 0) return a;
int flow = 0, f;
for(int& i = cur[x]; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) {
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}
int Maxflow(int s, int t) {
this->s = s; this->t = t;
int flow = 0;
while(BFS()) {
memset(cur, 0, sizeof(cur));
flow += DFS(s, INF);
}
return flow;
}
};
Dinic g;
struct Node{
int pos, kind;
Node(int pos=0, int kind=0){
this -> pos = pos;
this -> kind = kind;
}
}a[maxn];
int main(){
int t, kase = 0;
scanf("%d", &t);
while(t--){
kase++;
int n, d;
scanf("%d%d", &n, &d);
a[0] = Node(0, 1);
a[n+1] = Node(d, 1);
for(int i = 1;i <= n;i++){
char s[5];int pos, kind;
scanf("%1s-%d",s, &pos);
if(s[0] == 'B'){
a[i] = Node(pos, 1);
}
else{
a[i] = Node(pos, 0);
}
}
int l = 0, r = d;
int ans = d;
while(l <= r){
int mid = (r+l)/2;
g.ClearAll(2*n+5);
int source = 0, sink = 2*n+3;
for(int i = 0;i <= n+1;i++){
if(a[i].kind == 1){
g.AddEdge(i, i+n+2, INF);
}
else{
g.AddEdge(i, i+n+2, 1);
}
for(int j = i+1;j <= n+1;j++){
if(a[j].pos-a[i].pos <= mid){
g.AddEdge(i+n+2, j, INF);
}
}
}
if(g.Maxflow(source, sink) >= 2){
ans = mid;
r = mid-1;
}
else
l = mid+1;
}
printf("Case %d: %d\n", kase , ans);
}
return 0;
}