HDU 3549 Flow Problem (dinic模版 && isap模版)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549

题意:

        给你一个有向图,问你1到n的最大流。

dinic模版 (n*n*m)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int N = 1000; //点个数
 6 const int M = 10000; //边个数
 7 const int inf = 0x3f3f3f3f;
 8 struct Edge {
 9     int to, next, cap, flow;
10 }edge[M];
11 int tot, head[N];
12 void init() {
13     tot = 0;
14     memset(head, -1, sizeof(head));
15 }
16 inline void add(int u, int v, int w, int rw = 0) {
17     edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = 0;
18     edge[tot].next = head[u]; head[u] = tot++;
19     edge[tot].to = u; edge[tot].cap = rw; edge[tot].flow = 0;
20     edge[tot].next = head[v]; head[v] = tot++;
21 }
22 int Q[N];
23 int dep[N], cur[N], sta[N];
24 bool bfs(int s, int t, int n) {
25     int front = 0, tail = 0;
26     memset(dep, -1, sizeof(dep[0])*(n + 1));
27     dep[s] = 0;
28     Q[tail++] = s;
29     while(front < tail) {
30         int u = Q[front++];
31         for(int i = head[u]; ~i; i = edge[i].next) {
32             int v = edge[i].to;
33             if(edge[i].cap > edge[i].flow && dep[v] == -1) {
34                 dep[v] = dep[u] + 1;
35                 if(v == t)
36                     return true;
37                 Q[tail++] = v;
38             }
39         }
40     }
41     return false;
42 }
43 
44 int dinic(int s, int t, int n) {
45     int maxflow = 0;
46     while(bfs(s, t, n)) {
47         for(int i = 0; i < n; ++i)
48             cur[i] = head[i];
49         int u = s, tail = 0;
50         while(cur[s] != -1) {
51             if(u == t) {
52                 int tp = inf;
53                 for(int i = tail - 1; i >= 0; --i) {
54                     tp = min(tp, edge[sta[i]].cap - edge[sta[i]].flow);
55                 }
56                 maxflow += tp;
57                 for(int i = tail - 1; i >= 0; --i) {
58                     edge[sta[i]].flow += tp;
59                     edge[sta[i] ^ 1].flow -= tp;
60                     if(edge[sta[i]].cap - edge[sta[i]].flow == 0)
61                         tail = i;
62                 }
63                 u = edge[sta[tail] ^ 1].to;
64             } else if(cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + 1 == dep[edge[cur[u]].to]) {
65                 sta[tail++] = cur[u];
66                 u = edge[cur[u]].to;
67             } else {
68                 while(u != s && cur[u] == -1) {
69                     u = edge[sta[--tail] ^ 1].to;
70                 }
71                 cur[u] = edge[cur[u]].next;
72             }
73         }
74     }
75     return maxflow;
76 }
77 
78 int main()
79 {
80     int t, n, m, u, v, c;
81     scanf("%d", &t);
82     for(int ca = 1; ca <= t; ++ca) {
83         scanf("%d %d", &n, &m);
84         init();
85         for(int i = 1; i <= m; ++i) {
86             scanf("%d %d %d", &u, &v, &c);
87             add(u, v, c);
88         }
89         printf("Case %d: %d\n", ca, dinic(1, n, n));
90     }
91     return 0;
92 }

 貌似一般比dinic更优一点

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 using namespace std;
  5 const int N = 1e3 + 5;
  6 const int M = 1e4 + 5;
  7 const int inf = 0x3f3f3f3f;
  8 struct Edge {
  9     int to, next, cap, flow;
 10 }edge[M];
 11 int tot, head[N], gap[N], dep[N], cur[N];
 12 void init() {
 13     tot = 0;
 14     memset(head, -1, sizeof(head));
 15 }
 16 void addedge(int u, int v, int w, int rw = 0) {
 17     edge[tot].next = head[u]; edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = 0; head[u] = tot++;
 18     edge[tot].next = head[v]; edge[tot].to = u; edge[tot].cap = rw; edge[tot].flow = 0; head[v] = tot++;
 19 }
 20 int Q[N];
 21 void bfs(int start, int end) {
 22     memset(dep, -1, sizeof(dep));
 23     memset(gap, 0, sizeof(gap));
 24     gap[0] = 1;
 25     int front = 0, rear = 0;
 26     dep[end] = 0;
 27     Q[rear++] = end;
 28     while(front != rear) {
 29         int u = Q[front++];
 30         for(int i = head[u]; ~i; i = edge[i].next) {
 31             int v = edge[i].to;
 32             if(dep[v] != -1)
 33                 continue;
 34             Q[rear++] = v;
 35             dep[v] = dep[u] + 1;
 36             gap[dep[v]]++;
 37         }
 38     }
 39 }
 40 int S[N];
 41 int sap(int start, int end, int N) {
 42     bfs(start, end);
 43     memcpy(cur, head, sizeof(head));
 44     int top = 0;
 45     int u = start;
 46     int ans = 0;
 47     while(dep[start] < N) {
 48         if(u == end) {
 49             int Min = inf;
 50             int inser;
 51             for(int i = 0; i < top; ++i) {
 52                 if(Min > edge[S[i]].cap - edge[S[i]].flow) {
 53                     Min = edge[S[i]].cap - edge[S[i]].flow;
 54                     inser = i;
 55                 }
 56             }
 57             for(int i = 0; i < top; ++i) {
 58                 edge[S[i]].flow += Min;
 59                 edge[S[i] ^ 1].flow -= Min;
 60             }
 61             ans += Min;
 62             top = inser;
 63             u = edge[S[top] ^ 1].to;
 64             continue;
 65         }
 66         bool flag = false;
 67         int v;
 68         for(int i = cur[u]; ~i; i = edge[i].next) {
 69             v = edge[i].to;
 70             if(edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u]) {
 71                 flag = true;
 72                 cur[u] = i;
 73                 break;
 74             }
 75         }
 76         if(flag) {
 77             S[top++] = cur[u];
 78             u = v;
 79             continue;
 80         }
 81         int Min = N;
 82         for(int i = head[u]; ~i; i = edge[i].next) {
 83             if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) {
 84                 Min = dep[edge[i].to];
 85                 cur[u] = i;
 86             }
 87         }
 88         gap[dep[u]]--;
 89         if(!gap[dep[u]])
 90             return ans;
 91         dep[u] = Min + 1;
 92         gap[dep[u]]++;
 93         if(u != start)
 94             u = edge[S[--top] ^ 1].to;
 95     }
 96     return ans;
 97 }
 98 
 99 int main()
100 {
101     int t, n, m, u, v, c;
102     scanf("%d", &t);
103     for(int ca = 1; ca <= t; ++ca) {
104         scanf("%d %d", &n, &m);
105         init();
106         for(int i = 0; i < m; ++i) {
107             scanf("%d %d %d", &u, &v, &c);
108             addedge(u, v, c);
109         }
110         printf("Case %d: %d\n", ca, sap(1, n, n));
111     }
112     return 0;
113 }

 

posted @ 2016-10-11 21:21  Recoder  阅读(222)  评论(0编辑  收藏  举报