HDU 4289 Control 最小割

Control

题意:有一个犯罪集团要贩卖大规模杀伤武器,从s城运输到t城,现在你是一个特殊部门的长官,可以在城市中布置眼线,但是布施眼线需要花钱,现在问至少要花费多少能使得你及时阻止他们的运输。

题解:裸的最小割模型,最小割就是最大流,我们把点拆成2个点,然后将原点与拆点建边,流量为在城市建立眼线的费用,然后拆点为出点,原点为入点,将可以到达的城市之间建流量为无穷的边。

最后求出s 到 t的拆点的最大流 那么就是这个题目的答案了。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb emplace_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define lch(x) tr[x].son[0]
12 #define rch(x) tr[x].son[1]
13 #define max3(a,b,c) max(a,max(b,c))
14 #define min3(a,b,c) min(a,min(b,c))
15 typedef pair<int,int> pll;
16 const int inf = 0x3f3f3f3f;
17 const LL INF = 0x3f3f3f3f3f3f3f3f;
18 const LL mod =  (int)1e9+7;
19 const int N = 500;
20 const int M = N*N*4;
21 int head[N], deep[N], cur[N];
22 int w[M], to[M], nx[M];
23 int tot;
24 int n, m, s, t;
25 int u, v, val;
26 void add(int u, int v, int val){
27     w[tot]  = val; to[tot] = v;
28     nx[tot] = head[u]; head[u] = tot++;
29 
30     w[tot] = 0; to[tot] = u;
31     nx[tot] = head[v]; head[v] = tot++;
32 }
33 int bfs(int s, int t){
34     queue<int> q;
35     memset(deep, 0, sizeof(deep));
36     q.push(s);
37     deep[s] = 1;
38     while(!q.empty()){
39         int u = q.front();
40         q.pop();
41         for(int i = head[u]; ~i; i = nx[i]){
42             if(w[i] > 0 && deep[to[i]] == 0){
43                 deep[to[i]] = deep[u] + 1;
44                 q.push(to[i]);
45             }
46         }
47     }
48     return deep[t] > 0;
49 }
50 int Dfs(int u, int t, int flow){
51     if(u == t) return flow;
52     for(int &i = cur[u]; ~i; i = nx[i]){
53         if(deep[u]+1 == deep[to[i]] && w[i] > 0){
54             int di = Dfs(to[i], t, min(w[i], flow));
55             if(di > 0){
56                 w[i] -= di, w[i^1] += di;
57                 return di;
58             }
59         }
60     }
61     return 0;
62 }
63 
64 int Dinic(int s, int t){
65     int ans = 0, tmp;
66     while(bfs(s, t)){
67         for(int i = 1; i <= 2*n+2; i++) cur[i] = head[i];
68         while(tmp = Dfs(s, t, inf)) ans += tmp;
69     }
70     return ans;
71 }
72 void init(){
73     memset(head, -1, sizeof(head));
74     tot = 0;
75 }
76 int main(){
77     while(~scanf("%d%d", &n, &m)){
78         init();
79         int ss = n*2+1, tt = ss+1;
80         s = ss, t = tt;
81         scanf("%d%d", &ss, &tt);
82         add(s, ss, inf);
83         add(tt+n, t, inf);
84         for(int i = 1; i <= n; i++){
85             scanf("%d", &val);
86             add(i,i+n,val);
87         }
88         for(int i = 1; i <= m; i++){
89             scanf("%d%d",&u,&v);
90             add(u+n,v,inf);
91             add(v+n,u,inf);
92         }
93         printf("%d\n",Dinic(s,t));
94     }
95     return 0;
96 }
View Code

 

posted @ 2018-10-01 19:13  Schenker  阅读(172)  评论(0编辑  收藏  举报