题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289

题意:给你n个点,m条边,一个起点,一个终点,意思是一群***从起点出发到终点作案,要求你在一些点建立检查点,用最小的花费使得***到达不了终点。

由于是每个点上有花费,所以把点拆开,设置成  当前点到新点的距离为当前点的花费

即add(i,i + n,c);

m条边为

add(u+n,v,INF);

add(v+n,u,INF);

起点为s,终点为  t+n  

其他就是最大流模板

#include <algorithm>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAX = (1ll << 31) - 1;
const int mavn = 4e5+5;
const int maxn = 1e5+5;
#define ll long long
struct Edge{
    int to;
    ll dis;
    int rev;
    Edge(){}
    Edge(int to,ll d,int c):to(to),dis(d),rev(c){}
} ;
vector<Edge> v[maxn];

int n, m, s, t;
struct node {
    int u,v,d;
    ll c;
    node(){}
    node(int a,int b,ll c,int d):u(a),v(b),c(c),d(d){}
}pos[mavn];
void addEdge(int from, int to, ll dis){
    v[from].push_back(Edge(to, dis,v[to].size()));
    v[to].push_back(Edge(from, 0,v[from].size()-1));
}
int d[mavn],cnt, cur[mavn];
ll DFS(int u, ll flow){
    if (u == t || !flow) return flow;
    ll ans = 0, tmp_flow;
    for (int& i = cur[u]; i < v[u].size(); i++){
        int to = v[u][i].to;
        if (d[to] == d[u] + 1 && v[u][i].dis > 0){
            tmp_flow = DFS(to, min(flow, v[u][i].dis));
            if(tmp_flow > 0) {
                flow -= tmp_flow;
                v[u][i].dis -= tmp_flow;
                ans += tmp_flow;
                v[to][v[u][i].rev].dis += tmp_flow;
                if (!flow)
                    break;
            }
        }
    }
    if (!ans) d[u] = -1;
    return ans;
}
bool BFS(){
    memset(d,-1,sizeof(d));
    queue<int> que;
    que.push(s);
    d[s] = 0;
    int u, _new;
    while (!que.empty()){
        u = que.front();
        que.pop();
        for (int i = 0; i < v[u].size(); i++){
            _new = v[u][i].to;
            if (d[_new] == -1 && v[u][i].dis > 0){
                d[_new] = d[u] + 1;
                que.push(_new);
            }
        }
    }
    return (d[t] != -1);
}

ll  dinic(){
    ll max_flow = 0;
    while (BFS()){
        memset(cur,0,sizeof(cur));
        ll tt;
        while((tt = DFS(s,MAX)) > 0) max_flow += tt;
    }
    return max_flow;
}

int T;

int main(){
    while(scanf("%d%d",&n,&m)!=EOF) {
        scanf("%d%d",&s,&t);
        for(int i=1;i<=n;i++) {
            ll c;
            scanf("%lld",&c);
            addEdge(i,i+n,c);
        }
        for(int i=1 ; i<=m ; ++i){
            int a,b;
            scanf("%d %d",&a,&b);
    	    addEdge(a+n,b,MAX);
    	    addEdge(b+n,a,MAX);
        }
        t = t + n;
        printf("%lld\n",dinic());
        for(int i=0;i<=n*2;i++) v[i].clear();
    }
    return 0;
}