HDU 4289:Control(最小割)

http://acm.hdu.edu.cn/showproblem.php?pid=4289

题意:有n个城市,m条无向边,小偷要从s点开始逃到d点,在每个城市安放监控的花费是sa[i],问最小花费可以监控到所有小偷。

思路:求最小割可以转化为最大流。每个城市之间拆点,流量是sa[i],再增加一个超级源点S和s相连,增加一个超级汇点T,让d的第二个点和T相连。然后就可以做了。

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <string>
  6 #include <cmath>
  7 #include <queue>
  8 #include <vector>
  9 #include <map>
 10 #include <set>
 11 using namespace std;
 12 #define INF 0x3f3f3f3f
 13 #define N 100010
 14 #define M 510
 15 typedef long long LL;
 16 struct Edge {
 17     int v, nxt, cap;
 18     Edge () {}
 19     Edge (int v, int cap, int nxt) : v(v), cap(cap), nxt(nxt) {}
 20 }edge[N*10];
 21 int head[M], tot, gap[M], dis[M], cur[M], pre[M];
 22 int sa[M], S, T;
 23
 24 void Add(int u, int v, int cap) {
 25     edge[tot] = Edge(v, cap, head[u]); head[u] = tot++;
 26     edge[tot] = Edge(u, 0, head[v]); head[v] = tot++;
 27 }
 28
 29 void BFS() {
 30     memset(dis, -1, sizeof(dis));
 31     memset(gap, 0, sizeof(gap));
 32     queue<int> que; que.push(T);
 33     dis[T] = 0; gap[0]++;
 34     while(!que.empty()) {
 35         int u = que.front(); que.pop();
 36         for(int i = head[u]; ~i; i = edge[i].nxt) {
 37             Edge& e = edge[i];
 38             if(~dis[e.v]) continue;
 39             dis[e.v] = dis[u] + 1;
 40             gap[dis[e.v]]++;
 41             que.push(e.v);
 42         }
 43     }
 44 }
 45
 46 int ISAP(int n) {
 47     BFS(); // 别忘了调用!
 48     memcpy(cur, head, sizeof(cur));
 49     int u = pre[S] = S, ans = 0, i;
 50     while(dis[S] < n) {
 51         if(u == T) {
 52             int flow = INF, index;
 53             for(i = S; i != T; i = edge[cur[i]].v)
 54                 if(flow > edge[cur[i]].cap)
 55                     flow = edge[cur[i]].cap, index = i;
 56             for(i = S; i != T; i = edge[cur[i]].v)
 57                 edge[cur[i]].cap -= flow, edge[cur[i]^1].cap += flow;
 58             u = index; ans += flow;
 59         }
 60         for(i = cur[u]; ~i; i = edge[i].nxt)
 61             if(dis[edge[i].v] == dis[u] - 1 && edge[i].cap > 0) break;
 62         if(~i) {
 63             pre[edge[i].v] = u; cur[u] = i;
 64             u = edge[i].v;
 65         } else {
 66             if(--gap[dis[u]] == 0) break;
 67             int md = n;
 68             for(i = head[u]; ~i; i = edge[i].nxt)
 69                 if(edge[i].cap > 0 && dis[edge[i].v] < md)
 70                     md = dis[edge[i].v], cur[u] = i;
 71             ++gap[dis[u] = md + 1];
 72             u = pre[u];
 73         }
 74     }
 75     return ans;
 76 }
 77
 78 int main() {
 79     int n, m;
 80     while(~scanf("%d%d", &n, &m)) {
 81         int s, t;
 82         scanf("%d%d", &s, &t);
 83         memset(head, -1, sizeof(head)); tot = 0;
 84         S = 0, T = 2 * n + 1;
 85         // 第一个点是1~n,第二个点是n+1~2*n,第一个点为进来的点,第二个点为出去的点
 86         Add(S, s, INF); Add(t + n, T, INF);
 87         for(int i = 1; i <= n; i++) scanf("%d", &sa[i]);
 88         for(int i = 1; i <= m; i++) {
 89             int u, v;
 90             scanf("%d%d", &u, &v);
 91             Add(u + n, v, INF);
 92             Add(v + n, u, INF);
 93         }
 94         for(int i = 1; i <= n; i++)
 95             Add(i, i + n, sa[i]);
 96         int ans = ISAP(T + 1);
 97         printf("%d\n", ans);
 98     }
 99     return 0;
100 }
时间: 2024-10-12 18:30:28

HDU 4289:Control(最小割)的相关文章

HDU 4289 Control 最小割

Control 题意:有一个犯罪集团要贩卖大规模杀伤武器,从s城运输到t城,现在你是一个特殊部门的长官,可以在城市中布置眼线,但是布施眼线需要花钱,现在问至少要花费多少能使得你及时阻止他们的运输. 题解:裸的最小割模型,最小割就是最大流,我们把点拆成2个点,然后将原点与拆点建边,流量为在城市建立眼线的费用,然后拆点为出点,原点为入点,将可以到达的城市之间建流量为无穷的边. 最后求出s 到 t的拆点的最大流 那么就是这个题目的答案了. 代码: 1 #include<bits/stdc++.h>

HDU - 4289 Control (最小割 MCMF)

题目大意:有一个间谍要将一些机密文件送到目的地 现在给出间谍的初始位置和要去的目的地,要求你在间谍的必经路上将其拦获且费用最小 解题思路:最小割最大流的应用,具体可以看网络流–最小割最大流 建图的话 超级源点–起始城市,容量为INF 城市拆成两点(u, v),容量为监视该城市的代价 能连通的城市连接,容量为INF 目的地和超级汇点相连,容量为INF #include <cstdio> #include <cstring> #include <algorithm> #in

HDU 4289 Control (网络流-最小割)

Control Problem Description You, the head of Department of Security, recently received a top-secret information that a group of terrorists is planning to transport some WMD 1 from one city (the source) to another one (the destination). You know their

HDU 4289 Control (最大流+拆点)

http://acm.hdu.edu.cn/showproblem.php?pid=4289 题目讲的是有一些恐怖分子要从S市去往D市,要求在一些城市中安排特工,保证一定能够抓住恐怖分子,因为安排特工需要一定的费用,所以希望找出最小的花费. 思路:可以把每个城市,即每个点拆分成进来的点和出去的点,如x点分成x和x+n,两点连接的边权值为x点上安排特工的费用.而如果x和y两点有连线,则连接x+n,y,然后求从S市到达D市的最大流.之所以能这样求,是因为在求最大流的过程中每次所更新的流量是所有边中最

hdu 4289 Control(网络流 最大流+拆点)(模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289 Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1545    Accepted Submission(s): 677 Problem Description You, the head of Department o

hdu 4289 Control (最大流)

hdu 4289 Control You, the head of Department of Security, recently received a top-secret information that a group of terrorists is planning to transport some WMD 1 from one city (the source) to another one (the destination). You know their date, sour

hdu 4289 Control(最小割 + 拆点)

http://acm.hdu.edu.cn/showproblem.php?pid=4289 Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2247    Accepted Submission(s): 940 Problem Description You, the head of Department of Secu

HDU 4289 Control (最小割 拆点)

Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2139    Accepted Submission(s): 904 Problem Description You, the head of Department of Security, recently received a top-secret informati

HDU 4859 海岸线 最小割

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4859 题解: 这题考察的是最小割. 我们可以这样想:海岸线的长短变化都是E引起的,我们通过把’E'变成'.'或'D'来使海岸线最大化. 我们要算海岸线就是算格子‘.'和格子'D'(在原有地图周围四面都要加’D‘)相邻的面数,要使它最大,就是要使'.'与’.':'D'与'D'相邻的面数最小,而面数最小可以用最小割来做. 现在我们先把格子上的点黑白染色,(i+j)%2==1的为A类,为0的为B类, 在

HDU 3061 Battle(最小割----最大权闭合图)

题目地址:HDU 3061 多校中遇到的最小割的最大权闭合模型花了一上午时间终于看懂啦. 最大权闭合图就是将一些互相有依赖关系的点转换成图,闭合图指的是在图中的每一个点的后继点都是在图内的. 还要明白简单割的概念,就是指所有的割边都与源点或汇点相连.然后让源点与正权点相连,汇点与负权点相连,权值均为其绝对值,有依赖关系的点连一条有向边,如果a必须在b的基础上,那么就连一条a->b的有向边,权值为INF.最后用所有正权值得和减去最小割的值就是答案. 具体证明可看胡伯涛大牛的国家队集训论文<最小割