<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">一个城市交通图,上面有n个城市,m条双通道路,现在有个间谍要从s逃到t去,想要抓住他,但是只能在城市里面抓,不能在公路上,通过监控城市来实现抓捕,监控每个城市需要一定的费用,只要在所监控的城市出现了这个间谍就能抓住他,问抓住间谍的最小费用。</span>
就是不能让间谍到达t,可以转换成s到t的最小割,将城市拆点,容量为监控费用。
/*****************************************
Author :Crazy_AC(JamesQi)
Time :2016
File Name :最小割==最大流。
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 500;
const int maxm = 100000;
int head[maxn], cap[maxm], flow[maxm], pnt[maxm], nxt[maxm];
int ecnt;
inline void Addedge(int u,int v,int c) {
pnt[ecnt] = v, nxt[ecnt] = head[u], cap[ecnt] = c;
flow[ecnt] = 0, head[u] = ecnt++;
pnt[ecnt] = u, nxt[ecnt] = head[v], cap[ecnt] = 0;
flow[ecnt] = 0, head[v] = ecnt++;
}
int s, t;
int dis[maxn];
bool spfa() {
queue<int> que;
memset(dis, -1,sizeof dis);
dis[s] = 0;
que.push(s);
while(!que.empty()) {
int u = que.front();
que.pop();
// cout << u << ' ';
for (int i = head[u];i != -1;i = nxt[i]) {
int v = pnt[i];
if (cap[i] > flow[i] && dis[v] == -1) {
dis[v] = dis[u] + 1;
que.push(v);
}
}
}
// cout << endl;
return dis[t] != -1;
}
int dfs(int u,int a) {
if (u == t || a == 0) return a;
int ret = 0,f;
for (int i = head[u];i != -1;i = nxt[i]) {
int v = pnt[i];
if (dis[v] > dis[u] && (f = dfs(v, min(a, cap[i] - flow[i]))) > 0) {
ret += f;
a -= f;
flow[i] += f;
flow[i^1] -= f;
if (a == 0) break;
}
}
return ret;
}
int MaxFlow() {
int ret = 0;
while(spfa()) {
// cout << "here\n";
ret += dfs(s, INF);
}
return ret;
}
int n, m;
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
while(~scanf("%d%d",&n,&m)) {
s = 0,t = n*2 + 1;
int u, v, c;
scanf("%d%d",&u,&v);
memset(head, -1,sizeof head);
ecnt = 0;
Addedge(s, u, INF);
Addedge(v + n, t, INF);
for (int i = 1;i <= n;++i) {
scanf("%d",&c);
Addedge(i,i+n,c);
}
for (int i = 1;i <= m;++i) {
scanf("%d%d",&u,&v);
Addedge(u+n, v, INF);
Addedge(v+n, u, INF);
}
printf("%d\n", MaxFlow());
}
return 0;
}
/*****************************************
Author :Crazy_AC(JamesQi)
Time :2016
File Name :ISAP
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 500;
struct Edge{
int from, to, cap, flow;
Edge(){}
Edge(int from,int to,int cap,int flow)
:from(from),to(to),cap(cap),flow(flow){ }
};
struct ISAP{
int n, m, s, t;
bool vis[maxn];
int cur[maxn], num[maxn], dis[maxn], pre[maxn];
vector<Edge>edges;
vector<int>G[maxn];
void init(int n) {
this->n = n;
for (int i = 0;i <= n;++i) {
G[i].clear();
dis[i] = INF;
}
edges.clear();
}
void addedge(int u,int v,int c) {
edges.push_back(Edge(u, v, c, 0));
edges.push_back(Edge(v, u, 0, 0));
m = (int)edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
bool bfs() {
memset(vis, false,sizeof vis);
queue<int> que;
que.push(t);
dis[t] = 0;
vis[t] = true;
while(!que.empty()) {
int u = que.front();
que.pop();
for (int i = 0;i < G[u].size();++i) {
Edge& e = edges[G[u][i]^1];
if (e.cap > e.flow && !vis[e.from]) {
vis[e.from] = true;
dis[e.from] = dis[u] + 1;
que.push(e.from);
}
}
}
return vis[s];
}
int Augment() {
int u = t, flow = INF;
while(u != s) {
Edge& e = edges[pre[u]];
flow = min(flow, e.cap - e.flow);
u = edges[pre[u]].from;
}
u = t;
while(u != s) {
edges[pre[u]].flow += flow;
edges[pre[u]^1].flow -= flow;
u = edges[pre[u]].from;
}
return flow;
}
int MaxFlow(int s,int t) {
this->s = s, this->t = t;
int ret = 0;
bfs();
if (dis[s] >= n) return 0;
memset(num, 0,sizeof num);
memset(cur, 0,sizeof cur);
for (int i = 0;i < n;++i) {
if (dis[i] < INF) num[dis[i]]++;
}
int u = s;
while(dis[s] < n) {
if (u == t) {
ret += Augment();
u = s;
}
bool ok = false;
for (int i = cur[u];i < G[u].size();++i) {
Edge& e = edges[G[u][i]];
if (e.cap > e.flow && dis[u] == dis[e.to] + 1) {
ok = true;
pre[e.to] = G[u][i];
cur[u] = i;
u = e.to;
break;
}
}
if (!ok) {
int Min = n - 1;
for (int i = 0;i < G[u].size();++i) {
Edge& e = edges[G[u][i]];
if (e.cap > e.flow ) Min = min(Min, dis[e.to]);
}
if (--num[dis[u]] == 0) break;
num[dis[u] = Min + 1]++;
cur[u] = 0;
if (u != s) u = edges[pre[u]].from;
}
}
return ret;
}
};
ISAP isap;
int n, m;
int s, t;
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
while(~scanf("%d%d",&n,&m)) {
s = 0,t = n * 2 + 1;
isap.init(t+1);
int u, v, c;
scanf("%d%d",&u,&v);
isap.addedge(s, u, INF);
isap.addedge(v + n, t, INF);
for (int i = 1;i <= n;++i) {
scanf("%d",&c);
isap.addedge(i,i+n,c);
}
for (int i = 1;i <= m;++i) {
scanf("%d%d",&u,&v);
isap.addedge(u+n,v,INF);
isap.addedge(v+n,u,INF);
}
printf("%d\n", isap.MaxFlow(s, t));
}
return 0;
}