HDU 4289 Control(最小割)

来源:互联网 发布:floyd算法结果 编辑:程序博客网 时间:2024/05/22 03:32

题意分析转自 `Wind

题意: 有n个城市,有个小偷想从其中一个城市逃到另一个城市,警察想要堵截这个小偷,知道了在每个城市堵截的成本,问如何安排在哪些城市堵截可以使得

          小偷一定会被抓住,而且成本最低。

分析: 最小割模型,城市有成本限制,需要差点来限制,具体建图方法:

          将每个城市 i 拆成两个点 i 和 i + n, 之间连一条容量为该点花费的边,

          如果 城市 a 和 b 连通,则在 a+n 和 b, b+n 和 a 之间连一条容量为无穷的的边,

         这样可以保证最大流量即花费仅受到顶点容量的限制,

         如果 起点为 S ,终点为 D ,求出 点S 到 点 D+n 的最大流即为满足条件的最小割。

#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define INF 0x1f1f1ftypedef  struct {    int v, next, val;} edge;const int MAXN = 20010;const int MAXM = 500010;edge e[MAXM];int p[MAXN], eid;inline void init() {    memset(p, -1, sizeof(p));    eid = 0;}//有向inline void insert1(int from, int to, int val) {    e[eid].v = to;    e[eid].val = val;    e[eid].next = p[from];    p[from] = eid++;    swap(from, to);    e[eid].v = to;    e[eid].val = 0;    e[eid].next = p[from];    p[from] = eid++;}//无向inline void insert2(int from, int to, int val) {    e[eid].v = to;    e[eid].val = val;    e[eid].next = p[from];    p[from] = eid++;    swap(from, to);    e[eid].v = to;    e[eid].val = val;    e[eid].next = p[from];    p[from] = eid++;}int n, m; //n为点数 m为边数int h[MAXN];int gap[MAXN];int source, sink;inline int dfs(int pos, int cost) {    if (pos == sink) {        return cost;    }    int j, minh = n - 1, lv = cost, d;    for (j = p[pos]; j != -1; j = e[j].next){        int v = e[j].v, val = e[j].val;        if(val > 0){            if (h[v] + 1 == h[pos]) {                if (lv < e[j].val) d = lv;                else d = e[j].val;                d = dfs(v, d);                e[j].val -= d;                e[j ^ 1].val += d;                lv -= d;                if (h[source] >= n)return cost - lv;                if (lv == 0)break;            }            if (h[v] < minh)minh = h[v];        }    }    if (lv == cost) {        --gap[h[pos]];        if (gap[h[pos]] == 0)h[source] = n;        h[pos] = minh + 1;        ++gap[h[pos]];    }    return cost - lv;}int sap(int st, int ed) {    source = st;    sink = ed;    int ret = 0;    memset(gap, 0, sizeof(gap));    memset(h, 0, sizeof(h));    gap[0] = n;    while (h[st] < n)ret += dfs(st, INF);    return ret;}int main(){    int a,b,i,src,end;    while(scanf("%d%d",&n,&m)!=EOF){        init();        scanf("%d%d",&src,&end);        for(i=1;i<=n;i++){            scanf("%d",&a);            insert1(i,i+n,a);        }        while(m--){            scanf("%d%d",&a,&b);            insert1(a+n,b,INF);            insert1(b+n,a,INF);        }        n=n*2;        int res=sap(src,end+n/2);        printf("%d\n", res);    }    return 0;}


原创粉丝点击