bzoj1741 [Usaco2005 nov]Asteroids 穿越小行星群

  网络流,对于每一个行星,将行星所在行到行星连一条流量为1的边,将行星到其所在列连一条流量为1的边,从源点到所有行连一条流量为1的边,将所有列到汇点都连一条流量为1的边,最大流即为答案。

  代码

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define N 1000050
 4 #define M 1000050
 5 const int inf =0x37373737;
 6 using namespace std;
 7 int n,m,i,a,b;
 8 struct Dinic {
 9     int s, t, n, pre[N], cur[N], h[N], level[N], sign, q[N];
10     int cap[M], to[M], ne[M], flow, e;
11     void liu(int u, int v, int w) {
12         to[e] = v, ne[e] = h[u], cap[e] = w;
13         h[u] = e++;
14     }
15     void link(int u, int v, int w) {
16         liu(u, v, w);
17         liu(v, u, 0);
18     }
19     void init(int n) {
20         for (int i = 0; i <= n; ++i)
21             h[i] = -1;
22         e = 0;
23     }
24     bool bfs() {
25         int L = 0, R = 0;
26         fill(level, level + n, -1);
27         sign = q[R++] = t;
28         level[t] = 0;
29         while (L < R && level[s] == -1) {
30             int c = q[L++];
31             for (int k = h[c]; ~k; k = ne[k]) {
32                 if (cap[k ^ 1] > 0 && level[to[k]] == -1)
33                     level[to[k]] = level[c] + 1, q[R++] = to[k];
34             }
35         }
36         return ~level[s];
37     }
38     void push() {
39         int pl = inf, p, k;
40         for (p = t; p != s; p = to[k ^ 1]) {
41             k = pre[p];
42             pl = min(pl, cap[k]);
43         }
44         for (p = t; p != s; p = to[k ^ 1]) {
45             k = pre[p];
46             cap[k] -= pl;
47             cap[k ^ 1] += pl;
48             if (cap[k] == 0)
49                 sign = to[k ^ 1];
50         }
51         flow += pl;
52     }
53     void dfs(int c) {
54         if (c == t)
55             push();
56         else {
57             for (int &k = cur[c]; ~k; k = ne[k])
58                 if (cap[k] > 0 && level[to[k]] + 1 == level[c]) {
59                     pre[to[k]] = k;
60                     dfs(to[k]);
61                     if (level[sign] > level[c])
62                         return;
63                     sign = t;
64                 }
65             level[c] = -1;
66         }
67     }
68     int run(int _s, int _t, int _n) {
69         s = _s, t = _t, n = _n;
70         flow = 0;
71         while (bfs()) {
72             for (int i = 0; i < n; ++i)
73                 cur[i] = h[i];
74             dfs(s);
75         }
76         return flow;
77     }
78 } mf;
79 int main()
80 {
81     scanf("%d%d",&n,&m);
82     mf.init(2*n+m+10);
83     for (i=1;i<=n;i++) 
84     mf.link(0,i,1),mf.link(n+i,2*n+m+1,1);
85     for (i=1;i<=m;i++)
86     {
87         scanf("%d%d",&a,&b);
88         mf.link(a,2*n+i,1);
89         mf.link(2*n+i,n+b,1);
90     }
91     printf("%d
",mf.run(0,2*n+m+1,2*n+m+5));
92 }
原文地址:https://www.cnblogs.com/fzmh/p/5519005.html