uva 11157 - Dynamic Frog (二分 + 最大流)

D

Next Generation Contest 3

Time Limit: 2 seconds

Dynamic Frog

 

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-MSindicates 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;
}


你可能感兴趣的:(uva 11157 - Dynamic Frog (二分 + 最大流))