[Maximum flow, dinic] P2764 minimum path cover problem

  1 #include<iostream>
  2 #include<string>
  3 #include<queue>
  4 #include<stack>
  5 #include<vector>
  6 #include<map>
  7 #include<cstdio>
  8 #include<cstdlib>
  9 #include<algorithm>
 10 #include<set>
 11 #include<list>
 12 #include<iomanip>
 13 #include<cstring>
 14 #include<cmath>
 15 #include<limits>
 16 #include<fstream>
 17 using namespace std;
 18 
 19 template<typename type>
 20 inline type min(type& a, type& b)
 21 {
 22     return a < b ? a : b;
 23 }
 24 
 25 template<typename type>
 26 inline type max(type& a, type& b)
 27 {
 28     return a > b ? a : b;
 29 }
 30 
 31 #define debug(i) cout<<"<debug> "<<i<<" <\debug>"<<endl
 32 #define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
 33 #define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
 34 #define lll __int128
 35 #define Re register
 36 #define mem(a,b) memset(a,(b),sizeof(a))
 37 typedef pair<int, int> intpair;
 38 typedef pair<long long int, long long int> llpair;
 39 typedef long long int ll;
 40 const int INF = 0x3f3f3f3f;
 41 const long long int INFLL = 0x3f3f3f3f3f3f3f3f;
 42 
 43 const int maxn = 100010;
 44 int d[maxn];
 45 int now[maxn];
 46 const int st = 100008, ed = 100009;
 47 int n, m;
 48 int ans[maxn];
 49 int to[maxn];
 50 bool tag[maxn];
 51 int cnt;
 52 bool vis[maxn];
 53 
 54 struct Edge
 55 {
 56     int v, nxt;
 57     int w;
 58 }e[maxn];
 59 
 60 int head[maxn];
 61 
 62 void add_dinic(int u, int v)
 63 {
 64     e[++cnt].v = v;
 65     e[cnt].w = 0;
 66     e[cnt].nxt = head[u];
 67     head[u] = cnt;
 68 }
 69 
 70 void add(int u, int v, int w)
 71 {
 72     e[++cnt].v = v;
 73     e[cnt].nxt = head[u];
 74     head[u] = cnt;
 75     e[cnt].w = w;
 76     add_dinic(v, u);
 77 }
 78 
 79 int dfs_dinic(int x, int flow)
 80 {
 81     if (x == ed) return flow;
 82     int res = 0;
 83     for (int i = now[x]; i != -1; i = e[i].nxt)
 84     {
 85         int v = e[i].v;
 86         now[x] = i;
 87         if (d[v] + 1 == d[x] && e[i].w > 0)
 88         {
 89             int k = dfs_dinic(v, min(e[i].w, flow));
 90             if (k > 0 && x != st)
 91             {
 92                 tag[x] = true;
 93                 to[x] = v - n;
 94             }
 95             res += k;
 96             flow -= k;
 97             e[i].w -= k;
 98             e[i ^ 1].w += k;
 99             if (!flow) break;
100         }
101     }
102     return res;
103 }
104 
105 bool bfs_dinic()
106 {
107     memset(d, 0, sizeof(d));
108     queue<int>q;
109     q.push(ed);
110     d[ed] = 1;
111     while (!q.empty())
112     {
113         int u = q.front();
114         q.pop();
115         for (int i = head[u]; i != -1; i = e[i].nxt)
116         {
117             int v = e[i].v;
118             if (!d[v] && e[i ^ 1].w > 0)
119             {
120                 q.push(v);
121                 d[v] = d[u] + 1;
122             }
123         }
124     }
125     return d[st];
126 }
127 
128 
129 int dinic()
130 {
131     int flow = 0;
132     while (bfs_dinic())
133     {
134         for (int i = 0; i <= ed; i++) now[i] = head[i];
135         flow += dfs_dinic(st, INF);
136     }
137     return flow;
138 }
139 
140 int main()
141 {
142     cnt = 1;
143     memset(head, -1, sizeof(head));
144     cin >> n >> m;
145     mfor(i, 1, n)
146     {
147         add(st, i, 1);
148         add(i + n, ed, 1);
149     }
150     mfor(i, 1, m)
151     {
152         int a, b;
153         cin >> a >> b;
154         add(a, b + n, 1);
155     }
156     int maxf = dinic();
157     mfor(i, 1, n)
158         if (tag[i] && !vis[i])
159         {
160             int now = i;
161             vis[i] = true;
162             cout << now << " ";
163             while (to[now] && to[now] != ed)
164             {
165                 cout << to[now] << " ";
166                 vis[to[now]] = true;
167                 now = to[now];
168             }
169             cout << endl;
170         }
171     cout << n - maxf << endl;
172 }
View Code

 

Guess you like

Origin www.cnblogs.com/thjkhdf12/p/11935015.html