题意:

有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 构造最小割模型的更多相关文章

  1. 2019年杭电多校第二场 1008题Harmonious Army(HDU6598+最小割+建图)

    题目链接 传送门 题意 有\(n\)个士兵,要你给他们分配职业.有\(m\)对关系,对于某一对关系\(u,v\),如果同为勇士则总能力增加\(a\),同法师则增加\(c\),一个勇士一个法师增加\(\ ...

  2. 可持久化线段树的学习(区间第k大和查询历史版本的数据)(杭电多校赛第二场1011)

    以前我们学习了线段树可以知道,线段树的每一个节点都储存的是一段区间,所以线段树可以做简单的区间查询,更改等简单的操作. 而后面再做有些题目,就可能会碰到一种回退的操作.这里的回退是指回到未做各种操作之 ...

  3. SCNU省选校赛第二场B题题解

    今晚的校赛又告一段落啦,终于"开斋"了! AC了两题,还算是满意的,英语还是硬伤. 来看题目吧! B. Array time limit per test 2 seconds me ...

  4. 2015 多校赛 第二场 1006 (hdu 5305)

    Problem Description There are n people and m pairs of friends. For every pair of friends, they can c ...

  5. 2015 多校赛 第二场 1004 hdu(5303)

    Problem Description There are n apple trees planted along a cyclic road, which is L metres long. You ...

  6. 2015 多校赛 第二场 1002 (hdu 5301)

    Description Your current task is to make a ground plan for a residential building located in HZXJHS. ...

  7. 2019HDU多校赛第二场 H HDU 6598 Harmonious Army(最小割模型)

    参考博客https://blog.csdn.net/u013534123/article/details/97142191 #include<bits/stdc++.h> using na ...

  8. HDU 多校对抗赛第二场 1004 Game

    Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. HDU 多校对抗赛第二场 1010 Swaps and Inversions

    Swaps and Inversions Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

随机推荐

  1. readUTF()和writeUTF()

    readUTF()和writeUTF() 这是dataOutputStream 的方法~~使用utf-8编码 其实就是从unicode变过来的,utf8编码把unicode的ASCII编码变成1个字节 ...

  2. Linux-vim编辑器 常用命令 复制粘贴

    Linux-vim编辑器 一.vim三种工作模式 1.1.命令模式 在此模式下,可以使用上.下.左.右键或者 k.j.h.l 命令进行光标移动,还可以对文件内容进行复制.粘贴.替换.删除等操作. 1. ...

  3. 动态栈-------C语言

    使用带头结点的单链表实现 主要使用链表中的头插来实现栈的先进后出的特点 /***************************************************** Author:Si ...

  4. CSS:CSS 布局 - 水平 & 垂直对齐

    ylbtech-CSS:CSS 布局 - 水平 & 垂直对齐 1.返回顶部 1. CSS 布局 - 水平 & 垂直对齐 水平 & 垂直居中对齐 元素居中对齐 要水平居中对齐一个 ...

  5. docker集群故障迁移

    docker swarm 故障时候镜像迁移(无法添加新节点的时候)生产docker集群出现了故障,无法正常添加删除节点.在这样的情况下只能想办法把故障集群的镜像迁移到新的docker集群当中.将发生故 ...

  6. Access数据库中自动编号字段重置为1

    在清空一张ACESS数据库表后,在重添加数据之前,希望此表的自动编号能从1开始,怎么办呢? 下面的方法告诉我们,除了通过转存数据库表的方法外,还有几种更简单的方法: 方法一(前提:数据库表可带内容进行 ...

  7. 2017 ICPC Asia Urumqi A.coins (概率DP + 期望)

    题目链接:Coins Description Alice and Bob are playing a simple game. They line up a row of nn identical c ...

  8. java IO 类概述表

    列举常用的类方便查看,温故知新! byte input byte output character input character output Basic InputStream OutputStr ...

  9. Struts2入门示例(Myeclipse)

    1.新建Web项目在lib导入struts-2.3.37核心基础jar包 2.在WebRoot新建2个JSP demo1.jsp <%@ page language="java&quo ...

  10. javascript事件委托与"坑"

    问题 这是在工作中遇到的一个问题: 一个textarea文本框,需要动态监听输入文本个数 方案 通过谷歌查到一种完美的兼容方法 "如果使用 onkeydown.onkeypress.onke ...