P2887 [USACO07NOV]防曬霜Sunscreen
阿新 • • 發佈:2018-10-29
air using sdi void getchar cst evel 建圖 emp
總感覺貪心哪裏不對, 寫了個網絡流水過去了此題.
建圖不難, 從源點向每一種防曬霜連一條容量為防曬霜數量的邊, 再 \(O(N^2)\) 地從每一種防曬霜向可行的牛連一條容量為1的邊, 最後從每頭牛向匯點連一條容量為1的邊.
#include <queue> #include <vector> #include <cstdio> #include <cstring> #include <cassert> #include <iostream> #include <algorithm> using namespace std; typedef pair<int, int> P; const int MAXN = 2500 + 10; inline int read(){ char ch = getchar(); int x = 0; while(!isdigit(ch)) ch = getchar(); while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); return x; } int C, L; namespace dinic { struct edge { int to, cap, rev; };vector<edge> g[MAXN << 1]; int S, T; int iter[MAXN << 1], level[MAXN << 1]; inline void addedge(int u, int v, int c) { g[u].push_back((edge) {v, c, g[v].size()}); g[v].push_back((edge) {u, 0, g[u].size() - 1}); } inline bool bfs() { memset(level, 0, sizeof(level)); queue<int> q; q.push(S), level[S] = 1; while(!q.empty()) { int u = q.front(); q.pop(); for(int i = 0; i < (int) g[u].size(); i++) { edge &e = g[u][i]; if(e.cap && !level[e.to]) level[e.to] = level[u] + 1, q.push(e.to); } } return level[T]; } int dfs(int u, int flow) { if(u == T) return flow; for(int &i = iter[u]; i < (int) g[u].size(); i++) { edge &e = g[u][i]; if(e.cap && level[e.to] == level[u] + 1) { int d = dfs(e.to, min(flow, e.cap)); if(d) { e.cap -= d, g[e.to][e.rev].cap += d; return d; } } } return 0; } int maxflow(int s, int t) { S = s, T = t; int ans = 0, d = 0; while(bfs()) { memset(iter, 0, sizeof(iter)); while(d = dfs(S, (1 << 30)), d) ans += d; } return ans; } } P a[MAXN]; int main(){ cin>>C>>L; for(int i = 1; i <= C; i++) a[i].first = read(), a[i].second = read(); for(int i = L + 1; i <= C + L; i++) dinic::addedge(i, L + C + 1, 1); for(int i = 1; i <= L; i++) { int spf = read(), cov = read(); dinic::addedge(0, i, cov); for(int j = 1; j <= C; j++) if(a[j].first <= spf && spf <= a[j].second) dinic::addedge(i, j + L, 1); } printf("%d\n", dinic::maxflow(0, L + C + 1)); return 0; }
P2887 [USACO07NOV]防曬霜Sunscreen