永远不会被卡的Dinic

78,79行是精髓

61,148,149行是当前弧优化

  1 #include <cstring>
  2 #include <cstdio>
  3 #include <queue>
  4 
  5 #define Max 1000090
  6 #define INF 1e9
  7 
  8 void read (int &now)
  9 {
 10     now = 0;
 11     register char word = getchar ();
 12     while (word < '0' || word > '9')
 13         word = getchar ();
 14     while (word >= '0' && word <= '9')
 15     {
 16         now = now * 10 + word - '0';
 17         word = getchar ();
 18     }
 19 }
 20 
 21 int N, M, S, T;
 22 
 23 inline int min (int a, int b)
 24 {
 25     return a < b ? a : b;
 26 }
 27 
 28 class Net_Flow_Type
 29 {
 30     
 31     private :
 32         
 33         int __to[Max * 10];
 34         int __next[Max * 10];
 35         
 36         int __flow[Max * 10];
 37         
 38         int Edge_Count;
 39         int edge_list[Max];
 40         
 41         int deep[Max], Answer;
 42         
 43         int Queue[Max * 10];
 44         int Head, Tail;
 45         int __tech_[Max];
 46         
 47     public :
 48         
 49         Net_Flow_Type ()
 50         {
 51             Edge_Count = 1;    
 52             Answer = 0;
 53         }
 54         
 55         int Flowing (int now, int flow)
 56         {
 57             if (flow <= 0 || now == T)
 58                 return flow;
 59             int pos = 0, res;
 60             
 61             for (int &i = __tech_[now]; i; i = __next[i])
 62             {
 63                 if (deep[__to[i]] != deep[now] + 1 || __flow[i] <= 0)
 64                     continue;
 65                 res = Flowing (__to[i], std :: min (flow, __flow[i]));
 66                 if (res > 0)
 67                 {
 68                     flow -= res;
 69                     pos += res;
 70                     
 71                     __flow[i] -= res;
 72                     __flow[i ^ 1] += res;
 73                         
 74                     if (flow <= 0)
 75                         return pos;
 76                 }
 77             }
 78             if (pos != flow)
 79                 deep[now] = -1;
 80             return pos;
 81         }
 82         
 83         inline void Add_Edge (int from, int to, int flow)
 84         {
 85             Edge_Count ++;
 86             __to[Edge_Count] = to;
 87             
 88             __next[Edge_Count] = edge_list[from];
 89             edge_list[from] = Edge_Count;
 90             
 91             Edge_Count ++;
 92             __to[Edge_Count] = from;
 93                 
 94             __next[Edge_Count] = edge_list[to];
 95             edge_list[to] = Edge_Count;
 96             
 97             __flow[Edge_Count - 1] = flow;
 98             __flow[Edge_Count] = 0;
 99                  
100         }
101         
102         void Insert_edges ()
103         {
104             for (int i = 1, from, to, flow; i <= M; i ++)
105             {
106                 read (from);
107                 read (to);
108                 read (flow);
109                 
110                 this->Add_Edge (from, to, flow); 
111             }    
112         }
113         
114         bool Bfs (int Start)
115         {
116             
117             for (int i = 0; i <= N; i ++)
118                 deep[i] = -1;
119             Head = 0, Tail = 1;
120             Queue[Head] = Start;
121             
122             deep[Start] = 0;
123             register int now;
124             
125             while (Head < Tail)
126             {
127                 now = Queue[Head];
128                 Head ++;
129                 
130                 for (int i = edge_list[now]; i; i = __next[i])
131                     if (deep[__to[i]] == -1 && __flow[i])
132                     {
133                         deep[__to[i]] = deep[now] + 1;
134                         if (__to[i] == T)
135                             return true;
136                         
137                         Queue[Tail ++] = __to[i]; 
138                     }
139             }
140         
141             return deep[T] != -1;
142         }
143         
144         int Dinic ()
145         {
146             while (Bfs (S))
147             {
148                 for (int i = 0; i <= N; i ++)
149                     __tech_[i] = edge_list[i];
150                     
151                 Answer += Flowing (S, INF);
152             }
153             
154             return Answer;
155         }
156 };
157 
158 Net_Flow_Type Make;
159 
160 int main (int argc, char *argv[])
161 {
162     read (N);
163     read (M);
164     read (S);
165     read (T);
166     
167     Make.Insert_edges (); 
168     
169     printf ("%d", Make.Dinic ());
170     
171     return 0;
172 }
原文地址:https://www.cnblogs.com/ZlycerQan/p/7307258.html