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 ...
随机推荐
- Linux权限简析
- linux进阶之路(一):linux入门
Linux:开源.免费得开源系统.具有高效性.稳定性.安全性.处理多并发. Linux的发行版本:基于Linux,不同的安装软件 CentOS(RedHat开源版本) RedHat Ubuntu Su ...
- jQuery 封装的ajax
jquery封装的ajax 具体操作: $.get(url [,data] [,fn回调函数] [, dataType]); data:给服务器传递的数据,请求字符串 .json对象 都可以设 ...
- Codeforces 340B - Maximal Area Quadrilateral (计算几何)
Codeforces Round #198 (Div. 2) 题目链接:Maximal Area Quadrilateral Iahub has drawn a set of \(n\) points ...
- POJ 3805 Separate Points (判断凸包相交)
题目链接:POJ 3805 Problem Description Numbers of black and white points are placed on a plane. Let's ima ...
- LeetCode 最小栈
题目链接:https://leetcode-cn.com/problems/min-stack/ 题目大意 略.并且题目中要求的操作都要 O(1) 实现. 分析 用 2 个栈,一个普通栈,一个单调栈. ...
- java实现邮件定时发送
最近做项目时客户提出了一个需求:系统定时发送E-mail到其客户,达到通知的效果.先将实例分享给大家,如果确实有一些帮助的话,请大家来点掌声! 首先介绍java定时器(java.util.Timer) ...
- xshell6 远程连接时提示 WARNING! The remote SSH server rejected X11 forwarding request.
1.输入命令 vi /etc/ssh/sshd_config ,修改配置文件 2.将UserLogin no 的注释解除 3.执行yum install -y xorg-x11-font xorg ...
- Nginx学习——proxy_pass
参考官网:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass 定义:用来设置被代理服务器的协议(http或https ...
- 并发新构件之Semaphore:信号量
Semaphore :JDK描述,通常用于限制可以访问某些资源(物理或逻辑的)的线程数目.一句话说明了他的作用.信号量有一个虚拟的许可证池,new Semaphore(10):构造一个含有10个许可证 ...