单纯性与网络流
单纯性模板:
需要b > 0, xi > 0.
1 // 单纯性 2 // n+1 * m+1 矩阵 3 // 1~n 为约束 <= 右值 4 // n+1为目标最大值 5 // 对偶化直接转置即可 6 const int maxn = 1100, maxm = 11000; 7 const double eps = 1e-7, INF = 1e20; 8 int dcmp(double a) { return fabs(a)<eps?0:a<0?-1:1; } 9 int n , m; 10 double a[maxm][maxn]; 11 void pivot(int l , int e){ 12 for(int i = 1; i <= n; i++) if(i != l&&dcmp(a[i][e])){ 13 for(int j = 1; j <= m; j++) 14 if(j != e) a[i][j] -= a[i][e]/a[l][e]*a[l][j]; 15 a[i][e] /= -a[l][e]; 16 } 17 for(int i = 1; i <= m; i++) if(i != e) a[l][i] /= a[l][e]; a[l][e] = 1/a[l][e]; 18 } 19 20 double simplex(){ 21 double mn; 22 int e , l; 23 while(1){ 24 for(e=1;e<m;e++) if(dcmp(a[n][e]) > 0) break; 25 if(e == m) return -a[n][m]; 26 mn = INF; 27 for(int i=1;i<n;i++) if(dcmp(a[i][e]) > 0 && mn > a[i][m]/a[i][e]) mn = a[l=i][m]/a[i][e]; 28 if(mn == INF) return INF; 29 pivot(l, e); 30 } 31 }
bzoj1061
题意:有n天,第i天需要ai个志愿者,有m类志愿者,每类志愿者工作时间为[l,r],花费为ci,求最小花费
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1100, maxm = 11000; 5 const double eps = 1e-7, INF = 1e20; 6 int dcmp(double a) { return fabs(a)<eps?0:a<0?-1:1; } 7 int n , m; 8 double a[maxm][maxn]; 9 void pivot(int l , int e){ 10 for(int i = 1; i <= n; i++) if(i != l&&dcmp(a[i][e])){ 11 for(int j = 1; j <= m; j++) 12 if(j != e) a[i][j] -= a[i][e]/a[l][e]*a[l][j]; 13 a[i][e] /= -a[l][e]; 14 } 15 for(int i = 1; i <= m; i++) if(i != e) a[l][i] /= a[l][e]; a[l][e] = 1/a[l][e]; 16 } 17 18 double simplex(){ 19 double mn; 20 int e, l; 21 while(1){ 22 for(e=1;e<m;e++) if(dcmp(a[n][e]) > 0) break; 23 if(e == m) return -a[n][m]; 24 mn = INF; 25 for(int i=1;i<n;i++) if(dcmp(a[i][e]) > 0 && mn > a[i][m]/a[i][e]) mn = a[l=i][m]/a[i][e]; 26 if(mn == INF) return INF; 27 pivot(l, e); 28 } 29 } 30 31 int main() { 32 scanf("%d%d", &n, &m); 33 //对偶化 34 for(int i = 1; i <= n; i++) 35 scanf("%lf", &a[m+1][i]); 36 for(int i = 1, l, r, v; i <= m; i++) { 37 scanf("%d%d%d" , &l, &r, &v); 38 for(int j = l; j <= r; j++) a[i][j] = 1; 39 a[i][n+1] = v; 40 } 41 n++, m++; 42 swap(n, m); 43 printf("%d" , (int)(simplex()+0.50)); 44 return 0; 45 }
====================== 网络流分割线 ======================
模板
Dinic
1 template<typename flow_t> 2 struct Dinic{ 3 static const int N = 10010, M = 50000; 4 int head[N], d[N]; 5 int tot, sink, source, n; 6 struct Edge{ 7 int from, to, next; 8 flow_t cap, flow; 9 Edge(){} 10 Edge(int from, int to, int next, flow_t cap, flow_t flow):from(from), to(to), next(next), cap(cap), flow(flow){} 11 }edge[M]; 12 void init(int n) { 13 this->n = n; 14 memset(head, -1, sizeof(head[0])*n); 15 tot = 0; 16 } 17 void AddEdge(int u, int v, flow_t cap) { 18 edge[tot] = Edge(u, v, head[u], cap, 0); head[u] = tot++; 19 edge[tot] = Edge(v, u, head[u], 0, 0); head[u] = tot++; 20 } 21 bool bfs(int s) { 22 int u, v; 23 memset(d, 0, sizeof(d[0])*n); 24 queue<int> Q; 25 Q.push(s); 26 d[s] = 1; 27 while (!Q.empty()) { 28 u = Q.front(); Q.pop(); 29 if (u == sink) return true; 30 for (int i = head[u]; ~i; i = edge[i].next) { 31 v = edge[i].to; 32 if (!d[v]&&edge[i].cap-edge[i].flow > 0) { 33 d[v] = d[u] + 1; 34 Q.push(v); 35 } 36 } 37 } 38 return false; 39 } 40 flow_t dfs(int x, flow_t a) { 41 if (x == sink || a == 0) 42 return a; 43 flow_t f, flow = 0; 44 for (int i = head[x]; ~i; i = edge[i].next) { 45 int v = edge[i].to; 46 if (d[v] == d[x] + 1 && edge[i].cap - edge[i].flow > 0) { 47 f = dfs(v, min(a, edge[i].cap - edge[i].flow)); 48 edge[i].flow += f; 49 edge[i^1].flow -= f; 50 flow += f; 51 a -= f; 52 if (!a) break; 53 } 54 } 55 if (flow == 0) d[x] = 0; 56 return flow; 57 } 58 flow_t Maxflow(int source, int sink, flow_t need) { 59 flow_t flow = 0; 60 this->source = source; 61 this->sink = sink; 62 while (bfs(source)) { 63 flow += dfs(source, need-flow); 64 if (flow >= need) return flow; 65 } 66 return flow; 67 } 68 };
ISAP(morejarphone)
1 template<typename type> 2 struct Isap{//morejarphone 3 static const int N = 10010, M = 50000; 4 static const int INF = 0x3f3f3f3f; 5 int tot, n, s, t; 6 int head[N], gap[N], dep[N], pre[N], cur[N]; 7 struct Edge { 8 int to, next; 9 type cap, flow; 10 Edge(){} 11 Edge(int to, int next, type cap, type flow):to(to), next(next), cap(cap), flow(flow){} 12 }edge[M]; 13 14 void init(int n){ 15 this->n = n; 16 tot = 0; 17 memset(head, -1, sizeof head); 18 } 19 void add_edge(int u, int v, type w, type rw = 0){ 20 edge[tot] = Edge(v, head[u], w, 0); 21 head[u] = tot++; 22 edge[tot] = Edge(u, head[v], rw, 0); 23 head[v] = tot++; 24 } 25 type sap(int s, int t){ 26 this->s = s; 27 this->t = t; 28 memset(gap, 0, sizeof gap); 29 memset(dep, 0, sizeof dep); 30 memcpy(cur, head, sizeof head); 31 int u = s; 32 pre[u] = -1, gap[0] = n; 33 type ans = 0; 34 while(dep[s] < n){ 35 if(u == t){ 36 type Min = INF; 37 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]) 38 Min = min(Min, edge[i].cap-edge[i].flow); 39 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){ 40 edge[i].flow += Min; 41 edge[i^1].flow -= Min; 42 } 43 u = s; 44 ans += Min; 45 continue; 46 } 47 bool flag = false; 48 int v; 49 for(int i = cur[u]; i != -1; i = edge[i].next){ 50 v = edge[i].to; 51 if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){ 52 flag = true; 53 cur[u] = pre[v] = i; 54 break; 55 } 56 } 57 if(flag){ 58 u = v; 59 continue; 60 } 61 int Min = n; 62 for(int i = head[u]; i != -1; i = edge[i].next) 63 if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){ 64 Min = dep[edge[i].to]; 65 cur[u] = i; 66 } 67 if(--gap[dep[u]] == 0) break; 68 dep[u] = Min+1; 69 gap[dep[u]]++; 70 if(u != s) u = edge[pre[u]^1].to; 71 } 72 return ans; 73 } 74 };
1 #define type int 2 struct Edge { 3 int to, next; 4 type cap, flow; 5 Edge(){} 6 Edge(int to, int next, type cap, type flow):to(to), next(next), cap(cap), flow(flow){} 7 }; 8 struct Isap{ 9 Edge edge[M]; 10 int tot, head[N]; 11 int gap[N], dep[N], pre[N], cur[N]; 12 13 void init(){ 14 tot = 0; 15 memset(head, -1, sizeof head); 16 } 17 void add_edge(int u, int v, type w, type rw = 0){ 18 edge[tot] = Edge(v, head[u], w, 0); 19 head[u] = tot++; 20 edge[tot] = Edge(u, head[v], rw, 0); 21 head[v] = tot++; 22 } 23 type sap(int s, int t, int N){ 24 memset(gap, 0, sizeof gap); 25 memset(dep, 0, sizeof dep); 26 memcpy(cur, head, sizeof head); 27 int u = s; 28 pre[u] = -1, gap[0] = N; 29 type ans = 0; 30 while(dep[s] < N){ 31 if(u == t){ 32 type Min = INF; 33 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]) 34 Min = min(Min, edge[i].cap-edge[i].flow); 35 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){ 36 edge[i].flow += Min; 37 edge[i^1].flow -= Min; 38 } 39 u = s; 40 ans += Min; 41 continue; 42 } 43 bool flag = false; 44 int v; 45 for(int i = cur[u]; i != -1; i = edge[i].next){ 46 v = edge[i].to; 47 if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){ 48 flag = true; 49 cur[u] = pre[v] = i; 50 break; 51 } 52 } 53 if(flag){ 54 u = v; 55 continue; 56 } 57 int Min = N; 58 for(int i = head[u]; i != -1; i = edge[i].next) 59 if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){ 60 Min = dep[edge[i].to]; 61 cur[u] = i; 62 } 63 if(--gap[dep[u]] == 0) break; 64 dep[u] = Min+1; 65 gap[dep[u]]++; 66 if(u != s) u = edge[pre[u]^1].to; 67 } 68 return ans; 69 } 70 };
ISAP
1 template<typename type> 2 struct Isap{ 3 static const int N = 10010, M = 1000010; 4 static const int INF = 0x3f3f3f3f; 5 int tot, s, t, n; 6 int head[N], gap[N], d[N], pre[N], cur[N]; 7 bool vis[N]; 8 struct Edge{ 9 int from, to, next; 10 type cap, flow; 11 Edge(){} 12 Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){} 13 }edge[M]; 14 15 void init(int n){ 16 tot = 0; 17 this->n = n; 18 memset(head, -1, sizeof(head[0])*n); 19 } 20 void add_edge(int u, int v, type w, type rw = 0){ 21 edge[tot] = Edge(u, v, head[u], w, 0); 22 head[u] = tot++; 23 edge[tot] = Edge(v, u, head[v], rw, 0); 24 head[v] = tot++; 25 } 26 void bfs(){ 27 memset(d, -1, sizeof(d[0])*n); 28 memset(gap, 0, sizeof(gap));////////////////////// 29 queue<int> Q; 30 d[t] = 0, gap[0] = 1; 31 Q.push(t); 32 while(!Q.empty()){ 33 int u = Q.front(); Q.pop(); 34 for(int i = head[u]; i != -1; i = edge[i].next){ 35 int v = edge[i].to; 36 if(d[v] == -1){ 37 gap[ d[v] = d[u]+1 ]++; 38 Q.push(v); 39 } 40 } 41 } 42 } 43 type sap(int s, int t, int need){ 44 this->s = s; 45 this->t = t; 46 memcpy(cur, head, sizeof(cur[0])*n);///////////////////////// 47 type flow = 0; 48 bfs(); 49 int u = pre[s] = s, i; 50 while(d[s] < n){ 51 if(u == t){ 52 type f = INF; 53 for(i = s; i != t; i = edge[ cur[i] ].to) 54 if(f > edge[cur[i]].cap) f = edge[ cur[u = i] ].cap; 55 flow += f; 56 if(flow > need) return flow; 57 for(i = s; i != t; i = edge[cur[i]].to ) { 58 edge[cur[i]].cap -= f ; 59 edge[cur[i]^1].cap += f ; 60 } 61 } 62 for(i = cur[u]; ~i; i = edge[i].next) 63 if(edge[i].cap&&d[u] == d[edge[i].to]+1) break; 64 if(~i){ 65 cur[u] = i ; 66 pre[edge[i].to] = u; 67 u = edge[i].to; 68 }else{ 69 if(0 == --gap[d[u]]) break ; 70 int minv = n; 71 for(int i = head[u]; ~i; i = edge[i].next){ 72 int v = edge[i].to; 73 if(edge[i].cap&&minv > d[v]){ 74 minv = d[v]; 75 cur[u] = i; 76 } 77 } 78 d[u] = minv + 1 ; 79 gap[d[u]] ++ ; 80 u = pre[u] ; 81 } 82 } 83 return flow; 84 } 85 };
1 #define type int 2 #define M 1000010 3 #define N 10010 4 #define INF 0x3f3f3f3f 5 struct Edge{ 6 int from, to, next; 7 type cap, flow; 8 Edge(){} 9 Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){} 10 }; 11 int n, m, k, s, t; 12 struct Isap{ 13 Edge edge[M]; 14 int tot, head[N]; 15 int gap[N], d[N], pre[N], cur[N]; 16 bool vis[N]; 17 void init(){ 18 tot = 0; 19 memset(head, -1, sizeof head); 20 } 21 void add_edge(int u, int v, type w, type rw = 0){ 22 edge[tot] = Edge(u, v, head[u], w, 0); 23 head[u] = tot++; 24 edge[tot] = Edge(v, u, head[v], rw, 0); 25 head[v] = tot++; 26 } 27 void bfs(){/////////////////// 28 memset(d, -1, sizeof(d)); 29 memset(gap, 0, sizeof(gap)); 30 queue<int> Q; 31 d[t] = 0, gap[0] = 1; 32 Q.push(t); 33 while(!Q.empty()){ 34 int u = Q.front(); Q.pop(); 35 for(int i = head[u]; i != -1; i = edge[i].next){ 36 int v = edge[i].to; 37 if(d[v] == -1){ 38 gap[ d[v] = d[u]+1 ]++; 39 Q.push(v); 40 } 41 } 42 } 43 } 44 type sap(int s, int t, int n, int need){ 45 memcpy(cur, head, sizeof cur); 46 type flow = 0; 47 bfs(); 48 int u = pre[s] = s, i; 49 while(d[s] < n){ 50 if(u == t){ 51 type f = INF; 52 for(i = s; i != t; i = edge[ cur[i] ].to) 53 if(f > edge[cur[i]].cap) f = edge[ cur[u = i] ].cap; 54 flow += f; 55 if(flow > need) return flow; 56 for(i = s; i != t; i = edge[cur[i]].to ) { 57 edge[cur[i]].cap -= f ; 58 edge[cur[i]^1].cap += f ; 59 } 60 } 61 for(i = cur[u]; ~i; i = edge[i].next) 62 if(edge[i].cap&&d[u] == d[edge[i].to]+1) break; 63 if(~i){ 64 cur[u] = i ; 65 pre[edge[i].to] = u; 66 u = edge[i].to; 67 }else{ 68 if(0 == --gap[d[u]]) break ; 69 int minv = n; 70 for(int i = head[u]; ~i; i = edge[i].next){ 71 int v = edge[i].to; 72 if(edge[i].cap&&minv > d[v]){ 73 minv = d[v]; 74 cur[u] = i; 75 } 76 } 77 d[u] = minv + 1 ; 78 gap[d[u]] ++ ; 79 u = pre[u] ; 80 } 81 } 82 return flow; 83 } 84 };
费用流模板(摘自AngryBacon)
1 template<typename flow_t, typename cost_t> 2 struct MCMF { 3 static const int N = 1000, M = 50000; 4 const flow_t inf = 1e9; 5 struct node { 6 int from, to, nxt; 7 flow_t cap, flow; 8 cost_t cost; 9 node() {} 10 node(int from, int to, int nxt, flow_t cap, cost_t cost): 11 from(from), to(to), nxt(nxt), cap(cap), flow(0), cost(cost) {} 12 } E[M]; 13 cost_t dis[N]; 14 int G[N], pre[N], vis[N], n, m; 15 void init(int n) { 16 this->n = n; 17 this->m = 0; 18 std::fill(G, G + n, -1); 19 } 20 void link(int u, int v, flow_t f, cost_t c) { 21 E[m] = node(u, v, G[u], f, +c); G[u] = m++; 22 E[m] = node(v, u, G[v], 0, -c); G[v] = m++; 23 } 24 bool extand(int S, int T) { 25 std::fill(vis, vis + n, 0); 26 std::fill(dis, dis + n, inf); 27 std::queue<int> queue; 28 dis[S] = 0; 29 queue.push(S); 30 for (; !queue.empty(); queue.pop()) { 31 int u = queue.front(); 32 vis[u] = false; 33 for (int it = G[u]; ~it; it = E[it].nxt) { 34 int v = E[it].to; 35 if (E[it].cap > E[it].flow && dis[v] > dis[u] + E[it].cost) { 36 dis[v] = dis[u] + E[it].cost; 37 pre[v] = it; 38 if (!vis[v]) queue.push(v); 39 vis[v] = true; 40 } 41 } 42 } 43 return vis[T]; //改成dis[T] <= 0 求可行流 44 } 45 std::pair<flow_t, cost_t> run(int S, int T) { 46 flow_t max_flow = 0; 47 cost_t min_cost = 0; 48 while (extand(S, T)) { 49 flow_t delta = inf; 50 for (int u = T; u != S; u = E[pre[u]].from) { 51 delta = std::min(delta, E[pre[u]].cap - E[pre[u]].flow); 52 } 53 min_cost += delta * dis[T]; 54 max_flow += delta; 55 for (int u = T; u != S; u = E[pre[u]].from) { 56 E[pre[u]].flow += delta; 57 E[pre[u] ^ 1].flow -= delta; 58 } 59 } 60 return {max_flow, min_cost}; 61 } 62 };
费用流模板(如果cost是double型,注意cost精度)
1 struct Edge{ 2 int u, v, next, cap, flow; 3 type cost; 4 Edge(){} 5 Edge(int u, int v, int next, int cap, int flow, type cost):u(u), v(v), next(next), cap(cap), flow(flow), cost(cost){} 6 }; 7 8 Edge edge[maxm]; 9 int cnt, head[maxn], pre[maxn]; 10 type dis[maxn]; 11 bool vis[maxn]; 12 13 void init () { 14 memset (head, -1, sizeof head); 15 cnt = 0; 16 } 17 void add_edge(int u, int v, int cap, type cost) { 18 edge[cnt] = Edge(u, v, head[u], cap, 0, cost); 19 head[u] = cnt++; 20 edge[cnt] = Edge(v, u, head[v], 0, 0, -cost); 21 head[v] = cnt++; 22 } 23 bool spfa(int s, int t) { 24 queue<int> Q; 25 for(int i = 0; i < N; i++) 26 dis[i] = INF, vis[i] = 0, pre[i] = -1; 27 dis[s] = 0, vis[s] = 1; 28 Q.push(s); 29 while(!Q.empty()){ 30 int u = Q.front(); Q.pop(); 31 vis[u] = 0; 32 for(int i = head[u]; i != -1; i = edge[i].next){ 33 int v = edge[i].v; 34 if(edge[i].cap > edge[i].flow&&dis[v] > dis[u]+edge[i].cost){//注意精度 35 dis[v] = dis[u]+edge[i].cost; 36 pre[v] = i; 37 if (!vis[v]){ 38 vis[v] = 1; 39 Q.push(v); 40 } 41 } 42 } 43 } 44 return pre[t] != -1; 45 } 46 int MCMF(int s, int t, type &cost){ 47 int flow = 0; 48 cost = 0; 49 while(spfa(s, t)){ 50 int Min = INF; 51 for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){ 52 if (Min > edge[i].cap-edge[i].flow) 53 Min = edge[i].cap-edge[i].flow; 54 } 55 for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){ 56 edge[i].flow += Min; 57 edge[i^1].flow -= Min; 58 cost += edge[i].cost*Min; 59 } 60 flow += Min; 61 } 62 return flow; 63 }
hdu1532 裸最大流/模板测试
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define type ll 5 const int N = 1005, M = 50005; 6 const double INF = 1e16; 7 int n, m; 8 int s, t; 9 struct Edge { 10 int to, next; 11 type cap, flow; 12 Edge(){} 13 Edge(int to, int next, type cap, type flow):to(to), next(next), cap(cap), flow(flow){} 14 }; 15 Edge edge[M]; 16 int tot, head[N]; 17 int gap[N], dep[N], pre[N], cur[N]; 18 19 void init(){ 20 tot = 0; 21 memset(head, -1, sizeof head); 22 } 23 void add_edge(int u, int v, type w, type rw = 0){ 24 edge[tot] = Edge(v, head[u], w, 0); 25 head[u] = tot++; 26 edge[tot] = Edge(u, head[v], rw, 0); 27 head[v] = tot++; 28 } 29 type sap(int s, int t, int N){ 30 memset(gap, 0, sizeof gap); 31 memset(dep, 0, sizeof dep); 32 memcpy(cur, head, sizeof head); 33 int u = s; 34 pre[u] = -1, gap[0] = N; 35 type ans = 0; 36 while(dep[s] < N){ 37 if(u == t){ 38 type Min = INF; 39 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]) 40 Min = min(Min, edge[i].cap-edge[i].flow); 41 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){ 42 edge[i].flow += Min; 43 edge[i^1].flow -= Min; 44 } 45 u = s; 46 ans += Min; 47 continue; 48 } 49 bool flag = false; 50 int v; 51 for(int i = cur[u]; i != -1; i = edge[i].next){ 52 v = edge[i].to; 53 if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){ 54 flag = true; 55 cur[u] = pre[v] = i; 56 break; 57 } 58 } 59 if(flag){ 60 u = v; 61 continue; 62 } 63 int Min = N; 64 for(int i = head[u]; i != -1; i = edge[i].next) 65 if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){ 66 Min = dep[edge[i].to]; 67 cur[u] = i; 68 } 69 if(--gap[dep[u]] == 0) break; 70 dep[u] = Min+1; 71 gap[dep[u]]++; 72 if(u != s) u = edge[pre[u]^1].to; 73 } 74 return ans; 75 } 76 77 int main(){ 78 while(~scanf("%d%d", &n, &m)){ 79 init(); 80 int s, e, c; 81 for(int i = 0; i < n; i++){ 82 scanf("%d%d%d", &s, &e, &c); 83 add_edge(s, e, c, 0); 84 } 85 ll ans = sap(1, m, m); 86 printf("%lld\n", ans); 87 } 88 }
poj1695 简单最大流
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 using namespace std; 5 #define ll long long 6 #define type ll 7 const int N = 1005, M = 50005; 8 const double INF = 1e16; 9 int n, m; 10 int s, t; 11 struct Edge { 12 int to, next; 13 type cap, flow; 14 Edge(){} 15 Edge(int to, int next, type cap, type flow):to(to), next(next), cap(cap), flow(flow){} 16 }; 17 Edge edge[M]; 18 int tot, head[N]; 19 int gap[N], dep[N], pre[N], cur[N]; 20 21 void init(){ 22 tot = 0; 23 memset(head, -1, sizeof head); 24 } 25 void add_edge(int u, int v, type w, type rw = 0){ 26 edge[tot] = Edge(v, head[u], w, 0); 27 head[u] = tot++; 28 edge[tot] = Edge(u, head[v], rw, 0); 29 head[v] = tot++; 30 } 31 type sap(int s, int t, int N){ 32 memset(gap, 0, sizeof gap); 33 memset(dep, 0, sizeof dep); 34 memcpy(cur, head, sizeof head); 35 int u = s; 36 pre[u] = -1, gap[0] = N; 37 type ans = 0; 38 while(dep[s] < N){ 39 if(u == t){ 40 type Min = INF; 41 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]) 42 Min = min(Min, edge[i].cap-edge[i].flow); 43 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){ 44 edge[i].flow += Min; 45 edge[i^1].flow -= Min; 46 } 47 u = s; 48 ans += Min; 49 continue; 50 } 51 bool flag = false; 52 int v; 53 for(int i = cur[u]; i != -1; i = edge[i].next){ 54 v = edge[i].to; 55 if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){ 56 flag = true; 57 cur[u] = pre[v] = i; 58 break; 59 } 60 } 61 if(flag){ 62 u = v; 63 continue; 64 } 65 int Min = N; 66 for(int i = head[u]; i != -1; i = edge[i].next) 67 if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){ 68 Min = dep[edge[i].to]; 69 cur[u] = i; 70 } 71 if(--gap[dep[u]] == 0) break; 72 dep[u] = Min+1; 73 gap[dep[u]]++; 74 if(u != s) u = edge[pre[u]^1].to; 75 } 76 return ans; 77 } 78 int day[7]; 79 int main(){ 80 int t; scanf("%d", &t); 81 while(t--){ 82 init(); 83 scanf("%d", &n); 84 //1 ~ n 85 int d, w, maxw = -1, sum = 0; 86 for(int i = 1; i <= n; i++){ 87 for(int j = 0; j < 7; j++) 88 scanf("%d", day+j); 89 scanf("%d%d", &d, &w); 90 sum += d; 91 maxw = max(w, maxw); 92 add_edge(0, i, d, 0); 93 for(int j = 0; j < 7; j++) if(day[j]) 94 for(int k = 0; k < w; k++) 95 add_edge(i, n+k*7+j+1, 1, 0); 96 } 97 int s = 0, t = n+7*maxw+1; 98 for(int k = 0; k < maxw; k++) 99 for(int j = 0; j < 7; j++) 100 add_edge(n+k*7+j+1, t, 1, 0); 101 int ans = sap(s, t, t+1); 102 printf("%s\n", ans == sum? "Yes":"No"); 103 } 104 }
poj3204 关键割/残量网络搜索
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 using namespace std; 5 #define ll long long 6 #define type ll 7 const int N = 1005, M = 50005; 8 const double INF = 1e16; 9 int n, m; 10 int s, t; 11 struct Edge { 12 int from, to, next; 13 type cap, flow; 14 Edge(){} 15 Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){} 16 }; 17 Edge edge[M]; 18 int tot, head[N]; 19 int gap[N], dep[N], pre[N], cur[N]; 20 21 void init(){ 22 tot = 0; 23 memset(head, -1, sizeof head); 24 } 25 void add_edge(int u, int v, type w, type rw = 0){ 26 edge[tot] = Edge(u, v, head[u], w, 0); 27 head[u] = tot++; 28 edge[tot] = Edge(v, u, head[v], rw, 0); 29 head[v] = tot++; 30 } 31 type sap(int s, int t, int N){ 32 memset(gap, 0, sizeof gap); 33 memset(dep, 0, sizeof dep); 34 memcpy(cur, head, sizeof head); 35 int u = s; 36 pre[u] = -1, gap[0] = N; 37 type ans = 0; 38 while(dep[s] < N){ 39 if(u == t){ 40 type Min = INF; 41 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]) 42 Min = min(Min, edge[i].cap-edge[i].flow); 43 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){ 44 edge[i].flow += Min; 45 edge[i^1].flow -= Min; 46 } 47 u = s; 48 ans += Min; 49 continue; 50 } 51 bool flag = false; 52 int v; 53 for(int i = cur[u]; i != -1; i = edge[i].next){ 54 v = edge[i].to; 55 if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){ 56 flag = true; 57 cur[u] = pre[v] = i; 58 break; 59 } 60 } 61 if(flag){ 62 u = v; 63 continue; 64 } 65 int Min = N; 66 for(int i = head[u]; i != -1; i = edge[i].next) 67 if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){ 68 Min = dep[edge[i].to]; 69 cur[u] = i; 70 } 71 if(--gap[dep[u]] == 0) break; 72 dep[u] = Min+1; 73 gap[dep[u]]++; 74 if(u != s) u = edge[pre[u]^1].to; 75 } 76 return ans; 77 } 78 79 int vis[N]; 80 void dfs(int s){ 81 vis[s] = 1; 82 for(int i = head[s]; i != -1; i = edge[i].next) 83 if(!vis[edge[i].to]&&edge[i].cap > edge[i].flow){ 84 vis[edge[i].to] = 1; 85 dfs(edge[i].to); 86 } 87 } 88 void rdfs(int t){ 89 vis[t] = 2; 90 for(int i = head[t]; i != -1; i = edge[i].next) 91 //edge[i].cap-edge[i].flow: edge[i].to -> edge[i].from 残量 92 //edge[i^1].cap-edge[i^1].flow: edge[i].from -> edge[i].to 残量 93 if(!vis[edge[i].to]&&edge[i^1].cap > edge[i^1].flow){ 94 vis[t] = 2; 95 rdfs(edge[i].to); 96 } 97 } 98 99 int main(){ 100 init(); 101 scanf("%d%d", &n, &m); 102 int a, b, c; 103 for(int i = 0; i < m; i++){ 104 scanf("%d%d%d", &a, &b, &c); 105 add_edge(a, b, c); 106 } 107 sap(0, n-1, n); 108 dfs(0), rdfs(n-1); 109 int ans = 0; 110 for(int i = 0; i < tot; i += 2) 111 if(edge[i].cap == edge[i].flow&&vis[ edge[i].from ] == 1&&vis[ edge[i].to ] == 2) 112 ans++; 113 printf("%d\n", ans); 114 }
UVA11248 大白/保留原流量,多次修改容量求增广路
1 //UVA11248 2 #include <stdio.h> 3 #include <string.h> 4 #include <iostream> 5 #include <vector> 6 #include <algorithm> 7 using namespace std; 8 #define pii pair<int, int> 9 #define ll long long 10 #define type ll 11 const int N = 1005, M = 50005; 12 const double INF = 1e16; 13 int n, m; 14 int s, t; 15 ll c; 16 struct Edge { 17 int from, to, next; 18 type cap, flow; 19 Edge(){} 20 Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){} 21 }; 22 Edge edge[M]; 23 int tot, head[N]; 24 int gap[N], dep[N], pre[N], cur[N]; 25 26 void init(){ 27 tot = 0; 28 memset(head, -1, sizeof head); 29 } 30 void add_edge(int u, int v, type w, type rw = 0){ 31 edge[tot] = Edge(u, v, head[u], w, 0); 32 head[u] = tot++; 33 edge[tot] = Edge(v, u, head[v], rw, 0); 34 head[v] = tot++; 35 } 36 type sap(int s, int t, int N, ll limit){ 37 memset(gap, 0, sizeof gap); 38 memset(dep, 0, sizeof dep); 39 memcpy(cur, head, sizeof head); 40 int u = s; 41 pre[u] = -1, gap[0] = N; 42 type ans = 0; 43 while(dep[s] < N){ 44 if(u == t){ 45 type Min = INF; 46 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]) 47 Min = min(Min, edge[i].cap-edge[i].flow); 48 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){ 49 edge[i].flow += Min; 50 edge[i^1].flow -= Min; 51 } 52 u = s; 53 ans += Min; 54 if(ans >= limit) return ans; 55 continue; 56 } 57 bool flag = false; 58 int v; 59 for(int i = cur[u]; i != -1; i = edge[i].next){ 60 v = edge[i].to; 61 if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){ 62 flag = true; 63 cur[u] = pre[v] = i; 64 break; 65 } 66 } 67 if(flag){ 68 u = v; 69 continue; 70 } 71 int Min = N; 72 for(int i = head[u]; i != -1; i = edge[i].next) 73 if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){ 74 Min = dep[edge[i].to]; 75 cur[u] = i; 76 } 77 if(--gap[dep[u]] == 0) break; 78 dep[u] = Min+1; 79 gap[dep[u]]++; 80 if(u != s) u = edge[pre[u]^1].to; 81 } 82 return ans; 83 } 84 void clearFlow(){ 85 for(int i = 0; i < tot; i++) 86 edge[i].flow = 0; 87 } 88 89 //ll tmp[M]; 90 //void reset(){ 91 // for(int i = 0; i < tot; i++) 92 // edge[i].flow = tmp[i]; 93 //} 94 int main(){ 95 int ca = 1; 96 while(scanf("%d%d%lld", &n, &m, &c), n+m+c){ 97 init(); 98 int u, v, cap; 99 for(int i = 0; i < m; i++){ 100 scanf("%d%d%d", &u, &v, &cap); 101 add_edge(u, v, cap); 102 } 103 ll ans = sap(1, n, n, c); 104 printf("Case %d: ", ca++); 105 if(ans >= c) { 106 puts("possible"); 107 continue ; 108 } 109 110 for(int i = 0; i < tot; i++) 111 edge[i].cap -= edge[i].flow; 112 // for(int i = 0; i < tot; i++) 113 // tmp[i] = edge[i].flow; 114 115 vector< pii > ret; 116 for(int i = 0; i < tot; i += 2){ 117 if(edge[i].cap == 0) { 118 edge[i].cap = c; 119 clearFlow(); 120 if(ans+sap(1, n, n, c-ans) >= c) 121 ret.push_back( pii(edge[i].from, edge[i].to) ); 122 edge[i].cap = 0; 123 } 124 // if(edge[i].cap == edge[i].flow) { 125 // edge[i].cap += c; 126 // reset(); 127 // if(ans+sap(1, n, n, c-ans) >= c) 128 // ret.push_back( pii(edge[i].from, edge[i].to) ); 129 // edge[i].cap -= c; 130 // } 131 } 132 if(ret.empty()){ 133 puts("not possible"); 134 continue ; 135 } 136 printf("possible option:"); 137 sort(ret.begin(), ret.end()); 138 for(int i = 0; i < ret.size(); i++) 139 printf("(%d,%d)%c", ret[i].first, ret[i].second, ",\n"[i == ret.size()-1]); 140 } 141 }
UVALive2957 保留流量跑最大流,输出顺序
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #define debug 6 using namespace std; 7 8 #define type int 9 #define M 1000010 10 #define N 10010 11 #define INF 0x3f3f3f3f 12 struct Edge{ 13 int from, to, next; 14 type cap, flow; 15 Edge(){} 16 Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){} 17 }; 18 int n, m, k, s, t; 19 int u[N], v[N]; 20 struct Isap{ 21 Edge edge[M]; 22 int tot, head[N]; 23 int gap[N], d[N], pre[N], cur[N]; 24 bool vis[N]; 25 void init(){ 26 tot = 0; 27 memset(head, -1, sizeof head); 28 } 29 void add_edge(int u, int v, type w, type rw = 0){ 30 edge[tot] = Edge(u, v, head[u], w, 0); 31 head[u] = tot++; 32 edge[tot] = Edge(v, u, head[v], rw, 0); 33 head[v] = tot++; 34 } 35 void bfs(){/////////////////// 36 memset(d, -1, sizeof(d)); 37 memset(gap, 0, sizeof(gap)); 38 queue<int> Q; 39 d[t] = 0, gap[0] = 1; 40 Q.push(t); 41 while(!Q.empty()){ 42 int u = Q.front(); Q.pop(); 43 for(int i = head[u]; i != -1; i = edge[i].next){ 44 int v = edge[i].to; 45 if(d[v] == -1){ 46 gap[ d[v] = d[u]+1 ]++; 47 Q.push(v); 48 } 49 } 50 } 51 } 52 type sap(int s, int t, int n, int need){ 53 memcpy(cur, head, sizeof cur); 54 type flow = 0; 55 bfs(); 56 int u = pre[s] = s, i; 57 while(d[s] < n){ 58 if(u == t){ 59 type f = INF; 60 for(i = s; i != t; i = edge[ cur[i] ].to) 61 if(f > edge[cur[i]].cap) f = edge[ cur[u = i] ].cap; 62 flow += f; 63 if(flow > need) return flow; 64 for(i = s; i != t; i = edge[cur[i]].to ) { 65 edge[cur[i]].cap -= f ; 66 edge[cur[i]^1].cap += f ; 67 } 68 } 69 for(i = cur[u]; ~i; i = edge[i].next) 70 if(edge[i].cap&&d[u] == d[edge[i].to]+1) break; 71 if(~i){ 72 cur[u] = i ; 73 pre[edge[i].to] = u; 74 u = edge[i].to; 75 }else{ 76 if(0 == --gap[d[u]]) break ; 77 int minv = n; 78 for(int i = head[u]; ~i; i = edge[i].next){ 79 int v = edge[i].to; 80 if(edge[i].cap&&minv > d[v]){ 81 minv = d[v]; 82 cur[u] = i; 83 } 84 } 85 d[u] = minv + 1 ; 86 gap[d[u]] ++ ; 87 u = pre[u] ; 88 } 89 } 90 return flow; 91 } 92 93 int pos[N]; 94 void print(int cnt) { 95 for(int i = 1; i <= k; i++) pos[i] = s; 96 printf("%d\n", cnt); 97 for (int i = 1; i <= cnt; i++) { 98 vector<int> u, v; 99 memset(vis, 0, sizeof(vis)); 100 for (int j = 0; j < 4 * m; j += 4) { 101 int p = j + (i - 1) * 4 * m + n * i * 2; 102 //正向有流量,反向没流量,也就是u-->v 103 if(!edge[p].cap && edge[p+2].cap) { 104 u.push_back(edge[p ^ 1].to - (i - 1) * n); 105 v.push_back(edge[p].to - i * n); 106 }//反向有流量,正向没流量,也就是v-->u,这样的话就排除了两边都有流量的情况,相当于两点交换了,也就是两艘飞船待在原地了 107 else if (edge[p].cap && !edge[p + 2].cap) { 108 u.push_back(edge[(p + 2) ^ 1].to - (i - 1) * n); 109 v.push_back(edge[p + 2].to - i * n); 110 } 111 } 112 printf("%d", u.size()); 113 for (int p = 0; p < u.size(); p++) 114 for (int j = 1; j <= k; j++) { 115 if (!vis[j] && pos[j] == u[p]) { 116 vis[j] = 1; 117 printf(" %d %d", j, v[p]); 118 pos[j] = v[p]; 119 break; 120 } 121 } 122 printf("\n"); 123 } 124 } 125 }; 126 Isap isap; 127 128 int main(){ 129 while(~scanf("%d%d%d%d%d", &n, &m, &k, &s, &t)){ 130 for (int i = 0; i < m; i++) scanf("%d%d", u+i, v+i); 131 int cnt = 0, Maxflow = 0, sink = t; 132 isap.init(); 133 while (Maxflow < k) { 134 ++cnt; 135 for (int i = 1; i <= n; i++) isap.add_edge(i+(cnt-1)*n, i+cnt*n, INF); 136 for (int i = 0; i < m; i++){ 137 isap.add_edge(u[i]+(cnt-1)*n, v[i]+cnt*n, 1); 138 isap.add_edge(v[i]+(cnt-1)*n, u[i]+cnt*n, 1); 139 } 140 sink += n; 141 Maxflow += isap.sap(s, sink, n*cnt+n, k-Maxflow); 142 } 143 isap.print(cnt); 144 } 145 return 0; 146 }
Codeforces739E 概率期望/费用流
题意:小明有a个神奇宝贝球,b个超级神奇宝贝球,现在有n只神奇宝贝,两种球分别有pi, ui的概率抓到第i只神奇宝贝,一种球不能扔同一只神奇宝贝多次。问抓到的神奇宝贝个数的期望是多少?
题解:显然两种球各扔一次的抓到的概率是1-(1-pi)*(1-qi) = pi+ui-pi*ui.如何建图?某种球扔一次建边(1, -pi), 两种球各扔一次呢?从该点向汇点建两条边。第一条边是(1, 0),第二条边是(1, pi*ui), 扔一次显然会走第一条边,扔两次显然会经过第二条边。那么就有-pi-ui+pi*ui.注意精度
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define pii pair<int, int> 4 #define pll pair<ll, ll> 5 #define debug 6 #define lson l, m, rt<<1 7 #define rson m+1, r, rt<<1|1 8 #define type double 9 using namespace std; 10 const int maxm = 2e5+5, maxn = 2100; 11 #define INF 1e20 12 #define eps 1e-8 13 int s, t, N; 14 struct Edge{ 15 int u, v, next; 16 type cap, flow, cost; 17 Edge(){} 18 Edge(int u, int v, int next, type cap, type flow, type cost):u(u), v(v), next(next), cap(cap), flow(flow), cost(cost){} 19 }; 20 21 Edge edge[maxm]; 22 int cnt, head[maxn], pre[maxn]; 23 type dis[maxn]; 24 bool vis[maxn]; 25 26 void init () { 27 memset (head, -1, sizeof head); 28 cnt = 0; 29 } 30 void add_edge(int u, int v, type cap, type cost) { 31 edge[cnt] = Edge(u, v, head[u], cap, 0, cost); 32 head[u] = cnt++; 33 edge[cnt] = Edge(v, u, head[v], 0, 0, -cost); 34 head[v] = cnt++; 35 } 36 bool spfa(int s, int t) { 37 queue<int> Q; 38 for(int i = 0; i < N; i++) 39 dis[i] = INF, vis[i] = 0, pre[i] = -1; 40 dis[s] = 0, vis[s] = 1; 41 Q.push(s); 42 while(!Q.empty()){ 43 int u = Q.front(); Q.pop(); 44 vis[u] = 0; 45 for(int i = head[u]; i != -1; i = edge[i].next){ 46 int v = edge[i].v; 47 if(edge[i].cap > edge[i].flow+eps&&dis[v] > dis[u]+edge[i].cost+eps){//注意精度 48 dis[v] = dis[u]+edge[i].cost; 49 pre[v] = i; 50 if (!vis[v]){ 51 vis[v] = 1; 52 Q.push(v); 53 } 54 } 55 } 56 } 57 return pre[t] != -1; 58 } 59 type MCMF(int s, int t, type &cost){ 60 type flow = 0; 61 cost = 0; 62 while(spfa(s, t)){ 63 type Min = INF; 64 for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){ 65 if (Min > edge[i].cap-edge[i].flow) 66 Min = edge[i].cap-edge[i].flow; 67 } 68 for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){ 69 edge[i].flow += Min; 70 edge[i^1].flow -= Min; 71 cost += edge[i].cost*Min; 72 } 73 flow += Min; 74 } 75 return flow; 76 } 77 78 double p[2333], u[2333]; 79 int main(){ 80 int n, a, b; 81 scanf("%d%d%d", &n, &a, &b); 82 for(int i = 1; i <= n; i++) scanf("%lf", p+i); 83 for(int i = 1; i <= n; i++) scanf("%lf", u+i); 84 init(); 85 N = n+4; 86 add_edge(0, n+1, a, 0); 87 add_edge(0, n+2, b, 0); 88 for(int i = 1; i <= n; i++) 89 add_edge(n+1, i, 1, -p[i]); 90 for(int i = 1; i <= n; i++) 91 add_edge(n+2, i, 1, -u[i]); 92 for(int i = 1; i <= n; i++){ 93 add_edge(i, n+3, 1, 0); 94 add_edge(i, n+3, 1, p[i]*u[i]); 95 } 96 double ans; 97 MCMF(0, n+3, ans); 98 printf("%.5f\n", -ans); 99 return 0; 100 }
hdu5988 2016青岛费用流
1 //自从某次交上去后跑了951MS,之后再交就tle了 2 #include <bits/stdc++.h> 3 #define ll long long 4 #define pii pair<int, int> 5 #define pll pair<ll, ll> 6 #define debug 7 #define lson l, m, rt<<1 8 #define rson m+1, r, rt<<1|1 9 #define type double 10 using namespace std; 11 const int maxm = 2e5+5, maxn = 2100; 12 #define INF 2e9 13 #define eps 1e-6 14 int s, t, N; 15 struct Edge{ 16 int u, v, next, cap, flow; 17 type cost; 18 Edge(){} 19 Edge(int u, int v, int next, int cap, int flow, type cost):u(u), v(v), next(next), cap(cap), flow(flow), cost(cost){} 20 }; 21 22 Edge edge[maxm]; 23 int cnt, head[maxn], pre[maxn]; 24 type dis[maxn]; 25 bool vis[maxn]; 26 27 void init () { 28 memset (head, -1, sizeof head); 29 cnt = 0; 30 } 31 32 void add_edge(int u, int v, int cap, type cost) { 33 edge[cnt] = Edge(u, v, head[u], cap, 0, cost); 34 head[u] = cnt++; 35 edge[cnt] = Edge(v, u, head[v], 0, 0, -cost); 36 head[v] = cnt++; 37 } 38 int Q[10*maxn]; 39 bool spfa(int s, int t) { 40 //queue<int> Q; 41 int front = 0, quer = 0; 42 for(int i = 0; i < N; i++) 43 dis[i] = INF, vis[i] = 0, pre[i] = -1; 44 dis[s] = 0, vis[s] = 1; 45 Q[quer++] = s; 46 //Q.push(s); 47 //while(!Q.empty()){ 48 while(front != quer){ 49 int u = Q[front++]; 50 //int u = Q.front(); Q.pop(); 51 vis[u] = 0; 52 for(int i = head[u]; i != -1; i = edge[i].next){ 53 int v = edge[i].v; 54 if(edge[i].cap > edge[i].flow+eps&&dis[v] > dis[u]+edge[i].cost+eps){//注意精度 55 dis[v] = dis[u]+edge[i].cost; 56 pre[v] = i; 57 if (!vis[v]){ 58 vis[v] = 1; 59 Q[quer++] = v; 60 //Q.push(v); 61 } 62 } 63 } 64 } 65 return pre[t] != -1; 66 } 67 int MCMF(int s, int t, type &cost){ 68 int flow = 0; 69 cost = 0; 70 while(spfa(s, t)){ 71 int Min = INF; 72 for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){ 73 if (Min > edge[i].cap-edge[i].flow) 74 Min = edge[i].cap-edge[i].flow; 75 } 76 for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){ 77 edge[i].flow += Min; 78 edge[i^1].flow -= Min; 79 cost += edge[i].cost*Min; 80 } 81 flow += Min; 82 } 83 return flow; 84 } 85 86 int main(){ 87 int n, m, t; scanf("%d", &t); 88 while(t--){ 89 init(); 90 scanf("%d%d", &n, &m); 91 N = n+2; 92 int s, b; 93 for(int i = 1; i <= n; i++) { 94 scanf("%d%d", &s, &b); 95 int tmp = min(s, b); 96 s -= tmp, b -= tmp; 97 if(s) add_edge(0, i, s, 0); 98 if(b) add_edge(i, n+1, b, 0); 99 //add_edge(i, n+i, INF, 0); 100 } 101 int u, v, c; double p; 102 for(int i = 0; i < m; i++){ 103 scanf("%d%d%d%lf", &u, &v, &c, &p); 104 if(c){ 105 add_edge(u, v, 1, 0); 106 if(c > 1) 107 add_edge(u, v, c-1, -log(1.0-p) ); 108 } 109 } 110 111 double ans; 112 MCMF(0, n+1, ans); 113 ans = 1-exp(-ans); 114 printf("%.2f\n", ans); 115 } 116 return 0; 117 }
诸神对凡人心生艳羡,厌倦天堂。