HDU 4289 Control 最小割

时间:2023-03-09 18:57:14
HDU 4289 Control 最小割

Control

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

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

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

代码:

 #include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb emplace_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = ;
const int M = N*N*;
int head[N], deep[N], cur[N];
int w[M], to[M], nx[M];
int tot;
int n, m, s, t;
int u, v, val;
void add(int u, int v, int val){
w[tot] = val; to[tot] = v;
nx[tot] = head[u]; head[u] = tot++; w[tot] = ; to[tot] = u;
nx[tot] = head[v]; head[v] = tot++;
}
int bfs(int s, int t){
queue<int> q;
memset(deep, , sizeof(deep));
q.push(s);
deep[s] = ;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = head[u]; ~i; i = nx[i]){
if(w[i] > && deep[to[i]] == ){
deep[to[i]] = deep[u] + ;
q.push(to[i]);
}
}
}
return deep[t] > ;
}
int Dfs(int u, int t, int flow){
if(u == t) return flow;
for(int &i = cur[u]; ~i; i = nx[i]){
if(deep[u]+ == deep[to[i]] && w[i] > ){
int di = Dfs(to[i], t, min(w[i], flow));
if(di > ){
w[i] -= di, w[i^] += di;
return di;
}
}
}
return ;
} int Dinic(int s, int t){
int ans = , tmp;
while(bfs(s, t)){
for(int i = ; i <= *n+; i++) cur[i] = head[i];
while(tmp = Dfs(s, t, inf)) ans += tmp;
}
return ans;
}
void init(){
memset(head, -, sizeof(head));
tot = ;
}
int main(){
while(~scanf("%d%d", &n, &m)){
init();
int ss = n*+, tt = ss+;
s = ss, t = tt;
scanf("%d%d", &ss, &tt);
add(s, ss, inf);
add(tt+n, t, inf);
for(int i = ; i <= n; i++){
scanf("%d", &val);
add(i,i+n,val);
}
for(int i = ; i <= m; i++){
scanf("%d%d",&u,&v);
add(u+n,v,inf);
add(v+n,u,inf);
}
printf("%d\n",Dinic(s,t));
}
return ;
}