[BZOJ1163][BZOJ1339][Baltic2008]Mafia

[BZOJ1163][BZOJ1339][Baltic2008]Mafia

试题描述

匪徒准备从一个车站转移毒品到另一个车站,警方准备进行布控. 对于每个车站进行布控都需要一定的代价,现在警方希望使用最小的代价控制一些车站,使得去掉这些车站后,匪徒无法从原定的初始点到达目标点

输入

第一行输入N,M代表车站的总个数,及有多少条双向边连接它们. 2<=n<=200 , 1 <=m<=20000. 第二行给出两个数a,b,代表匪徒的出发点及目标点.1<=a,b<=N,a<>b. 再下来有N行,给出对第i个车站进行布控所需要的Money,其不超过10 000 000 再下来M行,用于描述图的结构.

输出

最少需要多少Money

输入示例

5 6
5 3
2
4
8
3
10
1 5
1 2
2 4
4 5
2 3
3 4

输出示例

5

数据规模及约定

见“输入

题解

一个点拆成一个“入点”A 和“出点”B,A → B 连一条容量为权值的有向边,无向边拆分成两个有向边,跑一边最小割。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;

const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *tail;
inline char Getchar() {
    if(Head == tail) {
        int l = fread(buffer, 1, BufferSize, stdin);
        tail = (Head = buffer) + l;
    }
    return *Head++;
}
int read() {
    int x = 0, f = 1; char c = Getchar();
    while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
    while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
    return x * f;
}

#define maxn 410
#define maxm 80410
#define oo 2147483647
struct Edge { int from, to, flow; } ;
struct Dinic {
	int n, m, s, t, head[maxn], next[maxm];
	Edge es[maxm];
	int vis[maxn], Q[maxn], hd, tl;
	int cur[maxn];
	void init(int nn) {
		n = nn; m = 0;
		memset(head, -1, sizeof(head));
		return ;
	}
	void AddEdge(int a, int b, int c) {
		es[m] = (Edge){ a, b, c }; next[m] = head[a]; head[a] = m++;
		es[m] = (Edge){ b, a, 0 }; next[m] = head[b]; head[b] = m++;
		return ;
	}
	bool BFS() {
		memset(vis, 0, sizeof(vis));
		vis[s] = 1;
		hd = tl = 0; Q[++tl] = s;
		while(hd < tl) {
			int u = Q[++hd];
			for(int i = head[u]; i != -1; i = next[i]) {
				Edge& e = es[i];
				if(e.flow && !vis[e.to]) {
					vis[e.to] = vis[u] + 1;
					Q[++tl] = e.to;
				}
			}
		}
		return vis[t] > 0;
	}
	int DFS(int u, int a) {
		if(u == t || !a) return a;
		int flow = 0, f;
		for(int& i = cur[u]; i != -1; i = next[i]) {
			Edge& e = es[i];
			if(vis[e.to] == vis[u] + 1 && (f = DFS(e.to, min(a, e.flow)))) {
				flow += f; a -= f;
				e.flow -= f; es[i^1].flow += f;
				if(!a) return flow;
			}
		}
		return flow;
	}
	int MinCut(int ss, int tt) {
		s = ss; t = tt;
		int flow = 0;
		while(BFS()) {
			for(int i = 1; i <= n; i++) cur[i] = head[i];
			flow += DFS(s, oo);
		}
		return flow;
	}
} sol;

int main() {
	int n = read(), m = read();
	sol.init(n << 1);
	int s = (read() << 1) - 1, t = read() << 1;
	for(int i = 1; i <= n; i++) sol.AddEdge((i << 1) - 1, i << 1, read());
	for(int i = 1; i <= m; i++) {
		int u = read(), v = read();
		sol.AddEdge(u << 1, (v << 1) - 1, oo);
		sol.AddEdge(v << 1, (u << 1) - 1, oo);
	}
	
	printf("%d\n", sol.MinCut(s, t));
	
	return 0;
}

 

posted @ 2016-05-09 22:03  xjr01  阅读(223)  评论(0编辑  收藏  举报