【模板】二分图匹配

嘟嘟嘟

这道题我其实是拿来练网络流的,用dinic。建图不说了(都给你建好了……)。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<stack>
 10 #include<queue>
 11 using namespace std;
 12 #define enter puts("") 
 13 #define space putchar(' ')
 14 #define Mem(a) memset(a, 0, sizeof(a))
 15 typedef long long ll;
 16 typedef double db;
 17 const int INF = 0x3f3f3f3f;
 18 const db eps = 1e-8;
 19 const int maxn = 2e3 + 5;
 20 inline ll read()
 21 {
 22     ll ans = 0;
 23     char ch = getchar(), last = ' ';
 24     while(!isdigit(ch)) {last = ch; ch = getchar();}
 25     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
 26     if(last == '-') ans = -ans;
 27     return ans;
 28 }
 29 inline void write(ll x)
 30 {
 31     if(x < 0) x = -x, putchar('-');
 32     if(x >= 10) write(x / 10);
 33     putchar(x % 10 + '0');
 34 }
 35 
 36 int n, m, E;
 37 int s, t;
 38 bool nds[maxn];
 39 
 40 struct Edge
 41 {
 42     int from, to, cap, flow;
 43 };
 44 vector<Edge> edges;
 45 vector<int> G[maxn];
 46 void addEdge(int from, int to)
 47 {
 48     edges.push_back((Edge){from, to, 1, 0});
 49     edges.push_back((Edge){to, from, 0, 0});
 50     int sz = edges.size();
 51     G[from].push_back(sz - 2);
 52     G[to].push_back(sz - 1);
 53 }
 54 
 55 int dis[maxn];            //记录距离和充当vis[] 
 56 bool bfs()
 57 {
 58     Mem(dis); dis[s] = 1;            //dis[s] = 1 一定要加,否则bfs可能死循环 
 59     queue<int> q; q.push(s);
 60     while(!q.empty())
 61     {
 62         int now = q.front(); q.pop();
 63         for(int i = 0; i < (int)G[now].size(); ++i)
 64         {
 65             Edge& e = edges[G[now][i]];
 66             if(!dis[e.to] && e.cap > e.flow)
 67             {
 68                 dis[e.to] = dis[now] + 1;
 69                 q.push(e.to);
 70             }
 71         }
 72     }
 73     return dis[t];
 74 }
 75 int cur[maxn];
 76 int dfs(int now, int res)
 77 {
 78     if(now == t || res == 0) return res;
 79     int flow = 0, f; 
 80     for(int& i = cur[now]; i < (int)G[now].size(); ++i)
 81     {
 82         Edge& e = edges[G[now][i]];
 83         if(dis[e.to] == dis[now] + 1 && (f = dfs(e.to, min(res, e.cap - e.flow))) > 0)
 84         {
 85             e.flow += f;
 86             edges[G[now][i] ^ 1].flow -= f;
 87             flow += f;
 88             res -= f;
 89             if(res == 0) break;
 90         }
 91     }
 92     return flow;
 93 }
 94 
 95 int maxflow(int s)
 96 {
 97     int flow = 0;
 98     while(bfs())
 99     {
100         Mem(cur);
101         flow += dfs(s, INF);
102     }
103     return flow;
104 }
105 
106 
107 int main()
108 {
109 //    freopen("testdata.in", "r", stdin);
110     n = read(); m = read(); E = read();
111     s = 0; t = n + m + 1;
112     for(int i = 1; i <= E; ++i)
113     {
114         int u = read(), v = read();
115         if(u > n || v > m) continue;
116         nds[u] = 1; nds[v + n] = 1;
117         addEdge(u, v + n);
118     }
119     for(int i = 1; i <= n; ++i) if(nds[i]) addEdge(s, i);
120     for(int i = n + 1; i <= n + m; ++i) if(nds[i]) addEdge(i, t);
121     write(maxflow(s)); enter;
122     return 0;
123 }
View Code

猜你喜欢

转载自www.cnblogs.com/mrclr/p/9579259.html