2019 HDU 多校赛第二场 HDU 6598 Harmonious Army 构造最小割模型
题意:
有n个士兵,你可以选择让它成为战士还是法师。
有m对关系,u和v 如果同时为战士那么你可以获得a的权值
如果同时为法师,你可以获得c的权值,
如果一个为战士一个是法师,你可以获得b的权值
问你可以获得的最大权值是多少?
题解:
对每个士兵建立一个点x ,点x 向源点s 连一条边,向汇点t 连一条边,
分别表示选择两种职业,然后就可以先加上所有的贡献,通过两点关系用 最小割建模,如下图所示
设一条边的三种贡献为A, B, C,可以得到以下方程:
如果x,y都是法师,你可以获得C的权值,但是我们构建的是最小割模型(这个权值C应该是A+B+C-该图的最小割),
我们选择x,y都是法师的最小割对应的权值应该是A+B,对应的边根据上述是a,b
所以有a+b=A+B
同理对于都是战士有公式c+d=B+C
对于一战士一法师有公式a+e+d=A+C b+e+c=A+C
存在一组解
a=b=(A+B)/2,c=d=(C+B)/2,e=-B+(A+C)/2;
为了消除浮点数的问题,我们建边的时候将边权*2,取答案的时候/2即可
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map> #define pi acos(-1.0)
#define eps 1e-9
#define fi first
#define se second
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("******\n")
#define mem(a, b) memset(a,b,sizeof(a))
#define name2str(x) #x
#define fuck(x) cout<<#x" = "<<x<<endl
#define sfi(a) scanf("%d", &a)
#define sffi(a, b) scanf("%d %d", &a, &b)
#define sfffi(a, b, c) scanf("%d %d %d", &a, &b, &c)
#define sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define sfL(a) scanf("%lld", &a)
#define sffL(a, b) scanf("%lld %lld", &a, &b)
#define sfffL(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)
#define sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d)
#define sfs(a) scanf("%s", a)
#define sffs(a, b) scanf("%s %s", a, b)
#define sfffs(a, b, c) scanf("%s %s %s", a, b, c)
#define sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d)
#define FIN freopen("../in.txt","r",stdin)
#define gcd(a, b) __gcd(a,b)
#define lowbit(x) x&-x
#define IO iOS::sync_with_stdio(false) using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const ULL seed = ;
const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = + ;
const int maxm = 2e5 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int n, m; struct MaxFlow {
struct Edge {
int v, nxt;
LL w;
} edge[maxm];
int tot, num, s, t;
int head[maxn]; void init() {
memset(head, -, sizeof(head));
tot = ;
} void add(int u, int v, LL w) {
edge[tot] = (Edge) {
v, head[u], w
};
head[u] = tot++;
edge[tot] = (Edge) {
u, head[v],
};
head[v] = tot++;
} int d[maxn], vis[maxn], gap[maxn]; void bfs() {
memset(d, , sizeof(d));
memset(gap, , sizeof(gap));
memset(vis, , sizeof(vis));
queue<int> q;
q.push(t);
vis[t] = ;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if (!vis[v]) {
d[v] = d[u] + ;
gap[d[v]]++;
q.push(v);
vis[v] = ;
}
}
}
} int last[maxn]; LL dfs(int u, LL f) {
if (u == t) return f;
LL sap = ;
for (int i = last[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if (edge[i].w > && d[u] == d[v] + ) {
last[u] = i;
LL tmp = dfs(v, min(f - sap, edge[i].w));
edge[i].w -= tmp;
edge[i ^ ].w += tmp;
sap += tmp;
if (sap == f) return sap;
}
}
if (d[s] >= num) return sap;
if (!(--gap[d[u]])) d[s] = num;
++gap[++d[u]];
last[u] = head[u];
return sap;
} LL solve(int st, int ed, int n) {
LL flow = ;
num = n;
s = st;
t = ed;
bfs();
memcpy(last, head, sizeof(head));
while (d[s] < num) flow += dfs(s, INFLL);
return flow;
}
} F; int main() {
//FIN;
while (~sffi(n, m)) {
F.init();
LL sum = ;
for (int i = , u, v, a, b, c; i < m; ++i) {
sffi(u, v);
sfffi(a, b, c);
F.add(, u, a + b);
F.add(, v, a + b);
F.add(u, n + , b + c);
F.add(v, n + , b + c);
F.add(u, v, - * b + a + c);
F.add(v, u, - * b + a + c);
sum += a + b + c;
}
printf("%lld\n", ( * sum - F.solve(, n + , n + )) / );
}
return ;
}
2019 HDU 多校赛第二场 HDU 6598 Harmonious Army 构造最小割模型的更多相关文章
- 2019年杭电多校第二场 1008题Harmonious Army(HDU6598+最小割+建图)
题目链接 传送门 题意 有\(n\)个士兵,要你给他们分配职业.有\(m\)对关系,对于某一对关系\(u,v\),如果同为勇士则总能力增加\(a\),同法师则增加\(c\),一个勇士一个法师增加\(\ ...
- 可持久化线段树的学习(区间第k大和查询历史版本的数据)(杭电多校赛第二场1011)
以前我们学习了线段树可以知道,线段树的每一个节点都储存的是一段区间,所以线段树可以做简单的区间查询,更改等简单的操作. 而后面再做有些题目,就可能会碰到一种回退的操作.这里的回退是指回到未做各种操作之 ...
- SCNU省选校赛第二场B题题解
今晚的校赛又告一段落啦,终于"开斋"了! AC了两题,还算是满意的,英语还是硬伤. 来看题目吧! B. Array time limit per test 2 seconds me ...
- 2015 多校赛 第二场 1006 (hdu 5305)
Problem Description There are n people and m pairs of friends. For every pair of friends, they can c ...
- 2015 多校赛 第二场 1004 hdu(5303)
Problem Description There are n apple trees planted along a cyclic road, which is L metres long. You ...
- 2015 多校赛 第二场 1002 (hdu 5301)
Description Your current task is to make a ground plan for a residential building located in HZXJHS. ...
- 2019HDU多校赛第二场 H HDU 6598 Harmonious Army(最小割模型)
参考博客https://blog.csdn.net/u013534123/article/details/97142191 #include<bits/stdc++.h> using na ...
- HDU 多校对抗赛第二场 1004 Game
Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 多校对抗赛第二场 1010 Swaps and Inversions
Swaps and Inversions Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
随机推荐
- git分布式版本控制系统权威指南学习笔记(四):git reset
文章目录 git reset目录树重写 git reset 重置 git reset目录树重写 git reset --soft 暂存区工作区不变 git reset --hard git reset ...
- 基于Netty的RPC架构学习笔记(十二):借助spring实现业务分离、聊天室小项目、netty3和4、5的不同、业务线程池以及消息串行化
文章目录 借助spring实现业务分离(
- flex上下、左右居中
tip:1)flex是用于div布局用的,作用于一级子元素(父元素写样式,作用于子元素) 2)弹性盒模型 3)英文解释justify-content: 对齐内容(内容一般写在主轴上)align-ite ...
- 前端(十三)—— JavaScript高级:回调函数、闭包、循环绑定、面向对象、定时器
回调函数.闭包.循环绑定.面向对象.定时器 一.函数高级 1.函数回调 // 回调函数 function callback(data) {} // 逻辑函数 function func(callbac ...
- 第十七章 程序管理与SELinux初探--进程、进程管理(ps、top)
一个程序被加载到内存当中运行,在内存内的那个数据就被称为进程(process).进程是操作系统上非常重要的概念,所有系统上面跑的数据都会以进程的类型存在.系统进程有哪些状态?不同状态会如何影响系统的运 ...
- Berry 指令设计
Berry 脚本源代码需要被编译为字节码指令流才能被 Berry 虚拟机执行.本文将详细地讲解 Berry 字节码指令(下面简称指令)的设计和实现.为了达到这个目的,本文由 3 部分构成:第 1 小节 ...
- linux 查看服务器序列号(S/N)
[root@node1~]# dmidecode -t 查看支持的参数 dmidecode: option requires an argument -- 't' Type number or key ...
- Echart中X轴为时间坐标刻度时,后台返回时间List被强制转化为时间戳问题
if(recordlist!=null&&recordlist.size()>0) { for (Record record : recordlist) { //根据频次决定使用 ...
- svg圆环缓冲动画
代码如下 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8& ...
- CSIC_716_20191207【并发编程---进程与线程】
僵尸进程与孤儿进程 ........... 守护进程 from Multiprocessing import Process 在 suboprocess.start( ) 的上一行,增加 subpr ...