BZOJ1458 士兵占领 【带上下界网络流】
2018-05-27 10:05
429 查看
题目链接
题解
对行列分别建边,拆点,设置流量下限
然后\(S\)向行连边\(inf\),列向\(T\)连边\(inf\),行列之间如果没有障碍,就连边\(1\)
然后跑最小可行流即可
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<map> #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt) #define REP(i,n) for (int i = 1; i <= (n); i++) #define mp(a,b) make_pair<int,int>(a,b) #define cls(s) memset(s,0,sizeof(s)) #define cp pair<int,int> #define LL long long int using namespace std; const int maxn = 505,maxm = 500005,INF = 1000000000; inline int read(){ int out = 0,flag = 1; char c = getchar(); while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();} while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();} return out * flag; } int h[maxn],ne = 1; struct EDGE{int to,nxt,f;}ed[maxm]; inline void build(int u,int v,int f){ ed[++ne] = (EDGE){v,h[u],f}; h[u] = ne; ed[++ne] = (EDGE){u,h[v],0}; h[v] = ne; } int vis[maxn],used[maxn],cur[maxn],d[maxn],S,T,now; int q[maxn],head,tail; bool bfs(){ vis[S] = now; d[S] = 0; q[head = tail = 0] = S; int u; while (head <= tail){ u = q[head++]; Redge(u) if (ed[k].f && vis[to = ed[k].to] != now){ d[to] = d[u] + 1; vis[to] = now; if (to == T) return true; q[++tail] = to; } } return vis[T] == now; } int dfs(int u,int minf){ if (u == T || !minf) return minf; int flow = 0,f,to; if (used[u] != now) cur[u] = h[u],used[u] = now; for (int& k = cur[u]; k; k = ed[k].nxt) if (vis[to = ed[k].to] == now && d[to] == d[u] + 1 && (f = dfs(to,min(ed[k].f,minf)))){ ed[k].f -= f; ed[k ^ 1].f += f; flow += f; minf -= f; if (!minf) break; } return flow; } int maxflow(){ int flow = 0; now = 1; while (bfs()){ flow += dfs(S,INF); now++; } return flow; } int n,m,K,L[105],C[105],del[105],de[105],g[105][105]; int main(){ n = read(); m = read(); K = read(); REP(i,n) L[i] = read(),del[i] = m; REP(i,m) C[i] = read(),de[i] = n; int a,b; while (K--){ a = read(); b = read(); g[a][b] = true; del[a]--; de[b]--; } S = 0; T = ((n + m) << 1) + 3; int SS = (n + m) << 1 | 1,TT = SS + 1,E = n + m; REP(i,n){ build(SS,i,INF); build(S,i + E,L[i]); build(i,T,L[i]); if (del[i] > L[i]) build(i,i + E,del[i] - L[i]); REP(j,m) if (!g[i][j]){ build(i + E,n + j,1); } } REP(i,m){ build(n + i + E,TT,INF); build(S,n + i + E,C[i]); build(n + i,T,C[i]); if (de[i] > C[i]) build(n + i,n + i + E,de[i] - C[i]); } maxflow(); build(TT,SS,INF); maxflow(); Redge(S) if (ed[k].f){puts("JIONG!"); return 0;} Redge(T) if (ed[k ^ 1].f){puts("JIONG!"); return 0;} printf("%d\n",ed[h[TT] ^ 1].f); return 0; }
相关文章推荐
- 【BZOJ】1458: 士兵占领(上下界网络流)
- 【BZOJ1458】士兵占领 网络流
- BZOJ 1458: 士兵占领( 网络流 )
- 【bzoj1458】【士兵占领】【网络流】
- 【网络流 最大流】【bzoj1458】士兵占领
- 【bzoj1458】士兵占领 有上下界最小流
- 【BZOJ1458】【洛谷4311】士兵占领(网络流)
- bzoj 1458: 士兵占领 网络流
- 【BZOJ1458】【洛谷4311】士兵占领(网络流)
- 【BZOJ1458】士兵占领 最小流
- BZOJ 1458: 士兵占领 网络最大流
- 【bzoj 1458】士兵占领
- BZOJ1458 士兵占领-最大流
- bzoj1458 士兵占领
- 【BZOJ1458】士兵占领 最大流的模板题
- [bzoj1458]士兵占领
- bzoj1458 士兵占领
- BZOJ1458 士兵占领
- [最大流] BZOJ 1458: 士兵占领 题解
- 【BZOJ1458】士兵占领