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 }