UVa11157 - Dynamic Frog(最大流)

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值