题意:有一个犯罪集团要贩卖大规模杀伤武器,从s城运输到t城,现在你是一个特殊部门的长官,可以在城市中布置眼线,但是布施眼线需要花钱,现在问至少要花费多少能使得你及时阻止他们的运输。
题解:裸的最小割模型,最小割就是最大流,我们把点拆成2个点,然后将原点与拆点建边,流量为在城市建立眼线的费用,然后拆点为出点,原点为入点,将可以到达的城市之间建流量为无穷的边。
最后求出s 到 t的拆点的最大流 那么就是这个题目的答案了。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include2 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<<110 #define rson m+1,r,rt<<1|111 #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 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 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 }