Codeforces contest 311 problem E. Biologist(最大权闭合子图)
2018-01-29 15:30
295 查看
传送门
题目大意
题解
GDKOI考成了垃圾,博客都不想写了,键盘都不想碰了,人生都觉得无意义了。一个简单的最大权闭合子图的模型。按照套路,将条件和变量都建点。S代表0的选择集合,T是1的集合。对于每个变量,是0与S连,否则与T连,如果割掉代表要花费V[i]的代价;对于每个条件,先收集其价值,再在连边上放上其价值(+代价),如果割掉就代表不要这部分的价值(+付出代价)。
同样向S或T连边,再向要求的变量连边(或者变量连向条件),容量为INF,代表如果构成S-T路径就要舍弃条件或者修改所连变量的所有值。然后跑一遍最小割。
时间复杂度玄学。
代码
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #define maxn 100010 #define maxm 1000100 #define INF 0x7FFFFFFF using namespace std; int s, t, cur = -1; struct List{ int obj, cap; List *next, *rev; }*head[maxn], *iter[maxn], Edg[maxm]; void Addedge(int a, int b, int c){ Edg[++cur].next = head[a]; Edg[cur].obj = b; Edg[cur].cap = c; Edg[cur].rev = Edg+(cur^1); head[a] = Edg+cur; } int q[maxn], level[maxn]; bool bfs(){ int hh = 0, tt = 0; for(int i = s; i <= t; i++) level[i] = -1; level[s] = 0; q[0] = s; while(hh <= tt){ int now = q[hh++]; for(List *p = head[now]; p; p = p->next){ int v = p->obj, c = p->cap; if(c && level[v] == -1){ level[v] = level[now] + 1; q[++tt] = v; } } } return ~ level[t]; } int Dinic(int now, int f){ if(now == t || !f) return f; int ret = 0; for(List *&p = iter[now]; p; p = p->next){ int v = p->obj, c = p->cap; if(c && level[now] + 1 == level[v]){ int d = Dinic(v, min(f, c)); f -= d; p->cap -=d; ret += d; p->rev->cap += d; if(!f) break; } } return ret; } int MinCut(){ int flow = 0; while(bfs()){ for(int i = s; i <= t; i++) iter[i] = head[i]; flow += Dinic(s, INF); } return flow; } int sum; int n, m, g; int V[maxn], F[maxn]; int main(){ scanf("%d%d%d", &n, &m, &g); for(int i = 1; i <= n; i++) scanf("%d", &F[i]); for(int i = 1; i <= n; i++) scanf("%d", &V[i]); s = 1; t = s + n + m + 1; for(int i = s; i <= t; i++) head[i] = NULL; for(int i = 1; i <= n; i++){ if(!F[i]){ Addedge(s, s+i, V[i]); Addedge(s+i, s, 0); } else{ Addedge(s+i, t, V[i]); Addedge(t, s+i, 0); } } int f, w, k, x; for(int i = 1; i <= m; i++){ scanf("%d%d%d", &f, &w, &k); sum += w; for(int j = 1; j <= k; j++){ scanf("%d", &x); if(!f){ Addedge(s+n+i, s+x, INF); Addedge(s+x, s+n+i, 0); } else{ Addedge(s+x, s+n+i, INF); Addedge(s+n+i, s+x, 0); } } scanf("%d", &x); if(!f){ Addedge(s, s+n+i, w+g*x); Addedge(s+n+i, s, 0); } else{ Addedge(s+n+i, t, w+g*x); Addedge(t, s+n+i, 0); } } printf("%d\n", sum - MinCut()); return 0; }
人生又是什麼呢 只是不明不白地活著
相关文章推荐
- codeforces com contest 855 problem D(数位DP)
- 2016 Multi-University Training Contest 4 09 String problem (hdu5772) 【最大权闭合子图】
- 【HDU】4971 A simple brute force problem. 强连通缩点+最大权闭合子图
- UvaLive 7037 The Problem Needs 3D Arrays 【最大密度子图-最大权闭合子图做法】
- codeforces contest 785 problem E(分块)
- codeforces contest 343 problem D(线段树+dfs序)
- HDU3879 Base Station 最大权闭合图/最大密度子图 2011 Multi-University Training Contest 5 - Host by BNU
- HDU4971 A simple brute force problem.(强连通分量缩点 + 最大权闭合子图)
- codeforces contest 868 problem C(补集 状压)
- codeforces contest 868 problem D(玄学)
- 2014-2015 ACM-ICPC, Asia Xian Regional Contest C – The Problem Needs 3D Arrays(最大密度子图)
- Codeforces Round #400 D. The Door Problem(2-sat)
- BZOJ1497: [NOI2006]最大获利[最小割 最大闭合子图]
- Codeforces Round #438 A+B+C Contest 868
- Codeforces Round 311 div2
- BZOJ 1497 [NOI2006]最大获利 最大权闭合子图
- Codeforces Problem 712A Memory and Crow
- Educational Codeforces Round 27 G. Shortest Path Problem?
- CODEFORCES problem 105A.Transmigration
- hdu 多校联合 4971 A simple brute force problem.(最大权闭合图)