HDU4289Control(最大流)

看了这道题,然后重新开始练习自己的刚敲不久的网络流,发现还是难以一遍敲得完整啊,,,,,

调了。。。遍,改了。。。遍,测了。。。遍,交了,,,遍,总算是A了,,不简单啊

然后试着用了其他两种算法EK和dinic都试着去练习一下,慢慢A了,,,真是不简单有木有

 

题目大意是这样的,有一些小偷打算从城市S到城市T,但是我们不知道他们会走哪些边,为了确保一定可以能够抓住所有的小偷,现在需要在某些城市布置一些警察,已知在城市i布置的花费是P[i],现在要使的抓住小偷的同时我的花费最小,求最小花费。

这里用到了最大流的一个定理,最小割最大流定理:当起点到终点的最大流算出来时,这个最大流就是将图划分为两个互不连通的集合的最小割。证明可以自己百度或看其他神牛的博客。

有了这个定理,就变成了裸的最大流问题了

下面我试着用三种方法做了这道题,比较了一下发现最快的依然是SAP,其次是dinic,最后是EK算法

SAP

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <vector>
  8 #include <cstdio>
  9 #include <cctype>
 10 #include <cstring>
 11 #include <cstdlib>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 #define INF 0x3f3f3f3f
 16 #define inf ((LL)1<<40)
 17 #define lson k<<1, L, mid
 18 #define rson k<<1|1, mid+1, R
 19 #define mem0(a) memset(a,0,sizeof(a))
 20 #define mem1(a) memset(a,-1,sizeof(a))
 21 #define mem(a, b) memset(a, b, sizeof(a))
 22 #define FOPENIN(IN) freopen(IN, "r", stdin)
 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
 24 template<class T> T ABS ( T a) { return a >= 0 ? a : -a;   }
 25 template<class T> T CMP_MIN ( T a, T b ) { return a < b;   }
 26 template<class T> T CMP_MAX ( T a, T b ) { return a > b;   }
 27 template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
 28 template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
 29 template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
 30 template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b;     }
 31 template<class T> void SWAP( T& a, T& b ) { T t = a; a = b;  b = t;     }
 32 
 33 typedef __int64 LL;
 34 //typedef long long LL;
 35 const int MAXN = 1010;
 36 const int MAXM = 200100;
 37 const double eps = 1e-14;
 38 const double PI = 4.0 * atan(1.0);
 39 const LL MOD = 1000000007;
 40 
 41 #define L(i) (i<<1)
 42 #define R(i) (i<<1|1)
 43 
 44 int m, n, s, d;
 45 struct Edge { int to, cap, next; }edge[MAXM<<3];
 46 int tot, head[MAXN];
 47 
 48 int src, des;
 49 int gap[MAXN], dep[MAXN], aug[MAXN], cur[MAXN],  pre[MAXN];
 50 
 51 void addEdge(int u, int v, int c)
 52 {
 53     edge[tot].to  = v; edge[tot].cap = c; edge[tot].next = head[u];
 54     head[u] = tot ++;
 55     edge[tot].to  = u; edge[tot].cap = 0; edge[tot].next = head[v];
 56     head[v] = tot ++;
 57 }
 58 
 59 void init()
 60 {
 61     int x, y;
 62     tot = 0;
 63     mem1(head); mem0(edge);
 64     scanf("%d %d", &s, &d);
 65     for(int i = 1; i <= n; i ++)
 66     {
 67         scanf("%d", &x);
 68         addEdge(L(i), R(i), x);
 69         addEdge(R(i), L(i), x);
 70     }
 71     for(int i = 0; i < m; i ++)
 72     {
 73         scanf("%d %d", &x, &y);
 74         addEdge(R(x), L(y), INF);
 75         addEdge(R(y), L(x), INF);
 76     }
 77     src = 0;
 78     des = (n+1)<<1;
 79     addEdge(src, L(s), INF);
 80     addEdge(R(d), des, INF);
 81 }
 82 
 83 int SAP(int n)
 84 {
 85     mem0(gap);
 86     mem0(dep);
 87     mem0(aug);
 88     mem0(pre);
 89     aug[src] = INF;
 90     pre[src] = -1;
 91     gap[0] = n;
 92     int max_flow = 0, u = src;
 93     for(int i = 0; i <= n; i ++)
 94         cur[i] = head[i];
 95     while(dep[src] < n)
 96     {
 97         if(u == des)
 98         {
 99             max_flow += aug[des];
100             for(int v = pre[des]; v != -1; v = pre[v])
101             {
102                 int id = cur[v];
103                 edge[id].cap   -= aug[des];
104                 edge[id^1].cap += aug[des];
105                 aug[v] -= aug[des];
106                 if(edge[id].cap == 0)
107                     u = v;
108             }
109         }
110         int flag = 0;
111         for(int i = cur[u]; i != -1; i = edge[i].next)
112         {
113             int v = edge[i].to;
114             if(edge[i].cap > 0 && dep[u] == dep[v]+1)
115             {
116                 flag = 1;
117                 pre[v]= u;
118                 cur[u] = i;
119                 aug[v] = MIN(aug[u], edge[i].cap);
120                 u = v;
121                 break;
122             }
123         }
124         if(!flag)
125         {
126             if(--gap[dep[u]] == 0)
127                 break;
128             int min_dep = n;
129             cur[u] = head[u];
130             for(int i = head[u]; i != -1; i = edge[i].next)
131             {
132                 int v = edge[i].to;
133                 if(edge[i].cap > 0 && dep[v] < min_dep)
134                 {
135                     min_dep = dep[v];
136                     cur[u] = i;
137                 }
138             }
139             dep[u] = min_dep + 1;
140             gap[dep[u]] ++;
141             if(pre[u] != -1) u = pre[u];
142         }
143     }
144     return max_flow;
145 }
146 
147 int main()
148 {
149     while(~scanf("%d %d", &n, &m))
150     {
151         init();
152         printf("%d\n", SAP(des));
153     }
154     return 0;
155 }

 

dinic

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <vector>
  8 #include <cstdio>
  9 #include <cctype>
 10 #include <cstring>
 11 #include <cstdlib>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 #define INF 0x3f3f3f3f
 16 #define inf ((LL)1<<40)
 17 #define lson k<<1, L, mid
 18 #define rson k<<1|1, mid+1, R
 19 #define mem0(a) memset(a,0,sizeof(a))
 20 #define mem1(a) memset(a,-1,sizeof(a))
 21 #define mem(a, b) memset(a, b, sizeof(a))
 22 #define FOPENIN(IN) freopen(IN, "r", stdin)
 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
 24 template<class T> T ABS ( T a) { return a >= 0 ? a : -a;   }
 25 template<class T> T CMP_MIN ( T a, T b ) { return a < b;   }
 26 template<class T> T CMP_MAX ( T a, T b ) { return a > b;   }
 27 template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
 28 template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
 29 template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
 30 template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b;     }
 31 template<class T> void SWAP( T& a, T& b ) { T t = a; a = b;  b = t;     }
 32 
 33 typedef __int64 LL;
 34 //typedef long long LL;
 35 const int MAXN = 1010;
 36 const int MAXM = 200100;
 37 const double eps = 1e-14;
 38 const double PI = 4.0 * atan(1.0);
 39 const LL MOD = 1000000007;
 40 
 41 #define L(i) (i<<1)
 42 #define R(i) (i<<1|1)
 43 
 44 int m, n, s, d;
 45 struct Edge { int to, cap, next; }edge[MAXM<<3];
 46 int tot, head[MAXN];
 47 
 48 int src, des;
 49 int dis[MAXN];
 50 
 51 void addEdge(int u, int v, int c)
 52 {
 53     edge[tot].to  = v; edge[tot].cap = c; edge[tot].next = head[u];
 54     head[u] = tot ++;
 55     edge[tot].to  = u; edge[tot].cap = 0; edge[tot].next = head[v];
 56     head[v] = tot ++;
 57 }
 58 
 59 void init()
 60 {
 61     int x, y;
 62     tot = 0;
 63     mem1(head); mem0(edge);
 64     scanf("%d %d", &s, &d);
 65     for(int i = 1; i <= n; i ++)
 66     {
 67         scanf("%d", &x);
 68         addEdge(L(i), R(i), x);
 69         addEdge(R(i), L(i), x);
 70     }
 71     for(int i = 0; i < m; i ++)
 72     {
 73         scanf("%d %d", &x, &y);
 74         addEdge(R(x), L(y), INF);
 75         addEdge(R(y), L(x), INF);
 76     }
 77     src = 0;
 78     des = (n+1)<<1;
 79     addEdge(src, L(s), INF);
 80     addEdge(R(d), des, INF);
 81 }
 82 
 83 bool bfs()
 84 {
 85     queue<int>q;
 86     mem1(dis);
 87     dis[src] = 0;
 88     q.push(src);
 89     while(!q.empty())
 90     {
 91         int u = q.front(); q.pop();
 92         for(int i = head[u]; i != -1; i = edge[i].next)
 93         {
 94             int v = edge[i].to;
 95             if(dis[v] == -1 && edge[i].cap > 0)
 96             {
 97                 dis[v] = dis[u] + 1;
 98                 q.push(v);
 99             }
100         }
101     }
102     return dis[des] != -1;
103 }
104 
105 int dfs(int cur, int aug)
106 {
107     if(cur == des || aug == 0)
108         return aug;
109     int flow = 0;
110     for(int i = head[cur]; i != -1; i = edge[i].next)
111     {
112         int v = edge[i].to;
113         if ( dis[v] == dis[cur]+1 && edge[i].cap > 0 )
114         {
115             int f = dfs( v, MIN(edge[i].cap, aug) );
116             edge[i].cap   -= f;
117             edge[i^1].cap += f;
118             flow += f;
119             aug -= f;
120             if(aug == 0)
121                 break;
122         }
123     }
124     return flow;
125 }
126 
127 int dinic()
128 {
129     int res = 0;
130     while (bfs())
131     {
132         res += dfs(src, INF);
133     }
134     return res;
135 }
136 
137 int main()
138 {
139     //FOPENIN("in.txt");
140     while(~scanf("%d %d", &n, &m))
141     {
142         init();
143         printf("%d\n", dinic());
144     }
145     return 0;
146 }

EK

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <vector>
  8 #include <cstdio>
  9 #include <cctype>
 10 #include <cstring>
 11 #include <cstdlib>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 #define INF 0x3f3f3f3f
 16 #define inf ((LL)1<<40)
 17 #define lson k<<1, L, mid
 18 #define rson k<<1|1, mid+1, R
 19 #define mem0(a) memset(a,0,sizeof(a))
 20 #define mem1(a) memset(a,-1,sizeof(a))
 21 #define mem(a, b) memset(a, b, sizeof(a))
 22 #define FOPENIN(IN) freopen(IN, "r", stdin)
 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
 24 template<class T> T ABS ( T a) { return a >= 0 ? a : -a;   }
 25 template<class T> T CMP_MIN ( T a, T b ) { return a < b;   }
 26 template<class T> T CMP_MAX ( T a, T b ) { return a > b;   }
 27 template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
 28 template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
 29 template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
 30 template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b;     }
 31 template<class T> void SWAP( T& a, T& b ) { T t = a; a = b;  b = t;     }
 32 
 33 typedef __int64 LL;
 34 //typedef long long LL;
 35 const int MAXN = 440;
 36 const int MAXM = 200100;
 37 const double eps = 1e-14;
 38 const double PI = 4.0 * atan(1.0);
 39 const LL MOD = 1000000007;
 40 
 41 #define L(i) (i<<1)
 42 #define R(i) (i<<1|1)
 43 
 44 int n, m, s, d;
 45 
 46 int src, des;
 47 int cap[MAXN][MAXN], flow[MAXN][MAXN], pre[MAXN], a[MAXN];
 48 
 49 void init()
 50 {
 51     int x, y;
 52     src = 1;
 53     des = (n+1)<<1;
 54     mem0(cap);mem0(pre);
 55     scanf("%d %d", &s, &d);
 56     cap[src][L(s)] = INF;
 57     cap[R(d)][des] = INF;
 58     for(int i = 1; i <= n; i ++)
 59     {
 60         scanf("%d", &x);
 61         cap[L(i)][R(i)] = x;
 62         cap[R(i)][L(i)] = x;
 63     }
 64     for(int i = 0; i < m; i ++)
 65     {
 66         scanf("%d %d", &x, &y);
 67         cap[R(x)][L(y)] = INF;
 68         cap[R(y)][L(x)] = INF;
 69     }
 70 }
 71 
 72 int EK(int n)
 73 {
 74     queue<int>q;
 75     mem0(flow);
 76     int max_flow = 0;
 77     while(true)
 78     {
 79         mem0(a);
 80         a[src] = INF;
 81         q.push(src);
 82         while(!q.empty())
 83         {
 84             int u = q.front(); q.pop();
 85             for(int v = 1; v <= n; v ++) if(!a[v] && cap[u][v]>flow[u][v])
 86             {
 87                 pre[v]= u;
 88                 q.push(v);
 89                 a[v] = MIN(a[u], cap[u][v] - flow[u][v]);
 90             }
 91         }
 92         if(a[des] == 0) break;
 93         for(int u = des; u != src; u = pre[u])
 94         {
 95             flow[pre[u]][u] += a[des];
 96             flow[u][pre[u]] -= a[des];
 97         }
 98         max_flow += a[des];
 99     }
100     return max_flow;
101 }
102 
103 int main()
104 {
105     //FOPENIN("in.txt");
106     while(~scanf("%d %d", &n, &m))
107     {
108         init();
109         printf("%d\n", EK(des));
110     }
111     return 0;
112 }

 

posted @ 2014-08-21 00:50  再见~雨泉  阅读(271)  评论(0编辑  收藏  举报