题意:

有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. tornado的安装

      centos6.4 安装tornado框架连接工具  xshell 工具 1.如果在windows下有tornado的安装包首先现在上装到linux下的上传工具:yum install lrzsz ...

  2. systemctl命令配置系统服务

    1.systemd的配置文件目录 systemd将daemon执行的脚本视作服务单位(unit),服务依据功能区分时,分为不同的类型(type). 常见的systemd服务类型如下表: 后缀名称    ...

  3. UDP 两种丢包处理策略:丢包重传(ARQ) 和 前向纠错(FEC)

    目录 1. 两种丢包处理策略 2. 前向纠错(FEC) 3. 丢包重传(ARQ) [参考文献] 1. 两种丢包处理策略 为了保证实时性,通常适应UDP协议来针对RTP数据进行传输,而UDP无法保证数据 ...

  4. 1、siege安装

    1.下载最新版本的siege wget http://download.joedog.org/siege/siege-latest.tar.gz 2.解压并进入siege路径 tar -zxvf si ...

  5. sed use case: Filter without editing

    if we want to filter with sed pattern and just print the filtered lines without any further editing ...

  6. DNF抽奖活动

    活动内容: DNF用户在注册页面注册获得抽奖资格(或分享好友注册)参与抽奖,产生奖品后,活动参与用户,在活动领奖页面领取奖品,金币及点券需填写相应游戏区服.qq号等信息,并且为防止活动刷子,在领取页提 ...

  7. 结对编程项目报告--四则运算CORE

    <!doctype html> sw_lab2.mdhtml {overflow-x: initial !important;}#write, body { height: auto; } ...

  8. No package docker-io available

    新手centos6.8安装docker时从遇到No package docker-io available开始的各种不小心的坑... 新安装了CentOS6.8,准备安装docker,执行命令 yum ...

  9. float f=3.4;是否正确?

    float f=3.4;是否正确? 不正确.3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换 ...

  10. Bribing FIPA

    Bribing FIPA 给出多棵有n个节点的有根树,第i个节点有一个权值\(a_i\),定义一个点能控制的点为其所有的子节点和它自己,询问选出若干个点的最少的权值之和,并且能够控制大于等于m个点,\ ...