这道题我其实是拿来练网络流的,用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