博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最大权闭合子图
阅读量:5231 次
发布时间:2019-06-14

本文共 4109 字,大约阅读时间需要 13 分钟。

学习链接

思路

将所有的活动与超级源点连起来,边权为活动的活跃值;学生与超级汇点连起来,边权为邀请学生的花费;将活动与所需要的学生连边,边权为\(inf\)。最后答案为所有活动的活跃值之和减去最小割。

代码实现如下

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long LL;typedef pair
pLL;typedef pair
pLi;typedef pair
pil;;typedef pair
pii;typedef unsigned long long uLL;#define lson rt<<1#define rson rt<<1|1#define lowbit(x) x&(-x)#define name2str(name) (#name)#define bug printf("*********\n")#define debug(x) cout<<#x"=["<
<<"]" <
q; int maxflow, tot, s, t; int head[maxn], d[maxn]; void init() { tot = maxflow = 0; memset(head, -1, sizeof(head)); } struct edge { int v, w, next; }ed[maxn*maxn]; void add(int u, int v, int w) { ed[tot].v = v; ed[tot].w = w; ed[tot].next = head[u]; head[u] = tot++; ed[tot].v = u; ed[tot].w = 0; ed[tot].next = head[v]; head[v] = tot++; } bool bfs() { memset(d, 0, sizeof(d)); d[s] = 1; while(!q.empty()) q.pop(); q.push(s); int x; while(!q.empty()) { x = q.front(); q.pop(); for(int i = head[x]; ~i; i = ed[i].next) { if(ed[i].w && !d[ed[i].v]) { d[ed[i].v] = d[x] + 1; q.push(ed[i].v); if(ed[i].v == t) return 1; } } } return 0; } int dinic(int x, int flow) { if(x == t) return flow; int res = flow, k, v; for(int i = head[x]; ~i && res; i = ed[i].next) { v = ed[i].v; if(ed[i].w && d[v] == d[x] + 1) { k = dinic(v, min(res, ed[i].w)); if(!k) d[v] = 0; ed[i].w -= k; ed[i^1].w += k; res -= k; } } return flow - res; } int work() { int flow = 0; while(bfs()) { while(flow = dinic(s, inf)) maxflow += flow; } return maxflow; }}f;int main() {#ifndef ONLINE_JUDGE FIN;#endif scanf("%d%d", &n, &m); f.s = 0, f.t = n + m + 1; f.init(); for(int i = 1; i <= m; ++i) { scanf("%d", &x); f.add(n + i, f.t, x); } int sum = 0; for(int i = 1; i <= n; ++i) { scanf("%d%d", &x, &num); f.add(f.s, i, x); sum += x; while(num--) { scanf("%d", &x); f.add(i, n + x, inf); } } printf("%d\n", sum - f.work()); return 0;}

思路

将智慧值的和与智力消耗值的和的差值为正的与源点连接,边权为差值,将智慧值的和与智力消耗值的和的差值为负的与汇点连接,边权为差值的绝对值,有前置技能的则将该技能与其前置技能点连边,边权为\(inf\),最后跑最大权闭合子图即可。

代码实现如下

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long LL;typedef pair
pLL;typedef pair
pLi;typedef pair
pil;;typedef pair
pii;typedef unsigned long long uLL;#define lson rt<<1#define rson rt<<1|1#define lowbit(x) x&(-x)#define name2str(name) (#name)#define bug printf("*********\n")#define debug(x) cout<<#x"=["<
<<"]" <
q; int maxflow, tot, s, t; int head[maxn], d[maxn]; void init() { tot = maxflow = 0; memset(head, -1, sizeof(head)); } struct edge { int v, w, next; }ed[maxn*maxn]; void add(int u, int v, int w) { ed[tot].v = v; ed[tot].w = w; ed[tot].next = head[u]; head[u] = tot++; ed[tot].v = u; ed[tot].w = 0; ed[tot].next = head[v]; head[v] = tot++; } bool bfs() { memset(d, 0, sizeof(d)); d[s] = 1; while(!q.empty()) q.pop(); q.push(s); int x; while(!q.empty()) { x = q.front(); q.pop(); for(int i = head[x]; ~i; i = ed[i].next) { if(ed[i].w && !d[ed[i].v]) { d[ed[i].v] = d[x] + 1; q.push(ed[i].v); if(ed[i].v == t) return 1; } } } return 0; } int dinic(int x, int flow) { if(x == t) return flow; int res = flow, k, v; for(int i = head[x]; ~i && res; i = ed[i].next) { v = ed[i].v; if(ed[i].w && d[v] == d[x] + 1) { k = dinic(v, min(res, ed[i].w)); if(!k) d[v] = 0; ed[i].w -= k; ed[i^1].w += k; res -= k; } } return flow - res; } int work() { int flow = 0; while(bfs()) { while(flow = dinic(s, inf)) maxflow += flow; } return maxflow; }}f;int main() {#ifndef ONLINE_JUDGE FIN;#endif scanf("%d", &n); f.s = 0, f.t = n + 1; f.init(); int sum = 0; for(int i = 1; i <= n; ++i) { scanf("%d%d", &x, &y); if(x - y >= 0) f.add(f.s, i, x - y), sum += x - y; else f.add(i, f.t, y - x); } while(~scanf("%d%d", &u, &v)) { f.add(v, u, inf); } printf("%d\n", sum - f.work()); return 0;}

转载于:https://www.cnblogs.com/Dillonh/p/11232837.html

你可能感兴趣的文章
兼容所有浏览器的实时监听输入的解决方案(转)
查看>>
JSON跨域解决方案收集
查看>>
【转】linux dumpe2fs命令
查看>>
SSH框架整合总结
查看>>
图的深度优先遍历
查看>>
C# 之 提高WebService性能大数据量网络传输处理
查看>>
Python面向对象之:三大特性:继承,封装,多态以及类的约束
查看>>
微信小程序实现类似JQuery siblings()的方法
查看>>
md5sum命令详解
查看>>
[bzoj1004] [HNOI2008] Cards
查看>>
使用 Swoole 来加速你的 Laravel 应用
查看>>
TextWatcher原因activity内存泄漏问题
查看>>
Merge into的使用具体解释-你Merge了没有
查看>>
Linux安装程序Anaconda分析
查看>>
如何在chrome上打开SSL3.0
查看>>
应该是实例化对象的没有对属性赋值时,自动赋值为null,但不是空指针对象引用...
查看>>
从网易与淘宝的font-size思考前端设计稿与工作流
查看>>
原生HttpClient详细使用示例
查看>>
几道面试题
查看>>
搜索引擎-SHODAN
查看>>