hdu多校第二场1008(hdu6598) Harmonious Army 最小割
题意:
一个军队有n人,你可以给他们每个人安排战士或者法师的职业,有m对人有组合技,组合技的信息是a,b,c,代表如果这两个人是两个战士,则组合技威力为a,一个战士一个法师,威力为b,其中b=a/4+c/3,两个法师,威力为c,求最大的威力。
题解:
这道题给出了一个最小割的清奇思路。
首先不去想边权,只想连通性,设源点为战士,汇点为法师,中间的点记为军队中的人,人和源点汇点之间连边,有组合技的人两两之间连边,简单起见,从只有两个人的情况讨论,这张图割完了只能是如下形式:

(两个战士)

(两个法师)

(1战士2法师)

(1法师2战士)
我们假想,求出了最小割,说明了每个人只选一种职业后的情况。那么,被割掉的,应该是这两个人选择其他职业的威力之和。
那么,边权怎么算呢?
可列出如下方程组
(源,1)+(源,2)=b+c
(源,1)+(2,汇)+(1,2)=(1,汇)+(源,2)+(1,2)=a+c
(1,汇)+(2,汇)=a+b
得到一组解
(源,1)=(源,2)=(a+b)/2
(1,汇)=(2,汇)=(c+b)/2
(1,2)=(a-2b+c)/2
以此建边,重复的边就是权值之和,求出最小割后,用所有职业组合的威力之和减去最小割,就是答案。
注意,题目数据保证了上述值都为正,但是做类似题时思路时不要僵化,必须是上述方程组解为正时才可应用此法。
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define per(i, a, b) for(int i=(b)-1; i>=(a); i--)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define pw(x) (1ll<<(x))
#define lb(x) ((x) & -(x))
#define endl "\n"
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int P = 1e9 + ;
int add(int a, int b) {if((a += b) >= P) a -= P; return a < ? a + P : a;}
int mul(int a, int b) {return 1ll * a * b % P;}
int kpow(int a, int b) {int r=;for(;b;b>>=,a=mul(a,a)) {if(b&)r=mul(r,a);}return r;}
//---- const int N = 1e3 + ;
const db eps = 1e-;
template<class T>
struct Dinic{
const static int N = , M = N * ;
int s , t , n , h[N] , cur[N] , lv[N] , q[N] , e , ne[M] , to[M];
T cap[M] , flow;
void liu(int u,int v,T w){ to[e] = v;ne[e] = h[u];cap[e] = w;h[u] = e++;}
void link(int u,int v,T w){ liu(u , v , w);liu(v , u , );}
void ini(int _n = N) { fill(h , h + (n=_n) , -);e = ;}
bool bfs(){
int L = , R = ;
fill(lv , lv + n , -);
lv[q[R++] = s] = ;
while(L < R && !~lv[t]){
int c = q[L++];
for(int k = h[c]; ~k ; k = ne[k])
if(cap[k] > && !~lv[to[k]])
lv[q[R++] = to[k]] = lv[c] + ;
}
return ~lv[t];
}
T dfs(int c,T mx){
if(c == t) return mx;
T ret = ;
for(int &k = cur[c]; ~k; k = ne[k]){
if(lv[to[k]] == lv[c] + && cap[k] > ){
T flow = dfs(to[k] , min(mx , cap[k]));
ret += flow;cap[k] -= flow , cap[k^] += flow;mx -= flow;
if (!mx) return ret;
}
}
lv[c] = -;
return ret;
}
T run(int _s,int _t){
s = _s , t = _t;
flow = ;
while(bfs()){
copy(h , h + n , cur);
flow += dfs(s, ~0U>>);
}
return flow;
}
}; Dinic<db> G; ll n, m, s, t, u, v, a, b, c, ans, w[N], ww[N]; int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(); while (cin >> n >> m) {
ans=;
rep(i,,n+) w[i]=ww[i]=; G.ini(n + ); s = G.n - ; t = s + ;
rep(i, , m+) {
cin >> u >> v >> a >> b >> c;
w[u] += a + b; w[v] += a + b;
ww[u] += b + c; ww[v] += b + c;
G.link(u, v, - b + a / 2.0 + c / 2.0);
G.link(v, u, - b + a / 2.0 + c / 2.0);
if (u > v) swap(u, v);
ans += a + c + b;
}
rep(i, , n+) G.link(s, i, w[i] / 2.0), G.link(i, t, ww[i] / 2.0);
ans = (ll)round(ans - G.run(s, t));
cout << ans << endl;
} return ;
}
hdu多校第二场1008(hdu6598) Harmonious Army 最小割的更多相关文章
- 2019年杭电多校第二场 1008题Harmonious Army(HDU6598+最小割+建图)
题目链接 传送门 题意 有\(n\)个士兵,要你给他们分配职业.有\(m\)对关系,对于某一对关系\(u,v\),如果同为勇士则总能力增加\(a\),同法师则增加\(c\),一个勇士一个法师增加\(\ ...
- [2019杭电多校第二场][hdu6598]Harmonious Army(最小割)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6598 题意是说一个军队有n人,你可以给他们每个人安排战士或者法师的职业,有m对人有组合技,组合技的信息 ...
- [2019杭电多校第一场][hdu6582]Path(最短路&&最小割)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582 题意:删掉边使得1到n的最短路改变,删掉边的代价为该边的边权.求最小代价. 比赛时一片浆糊,赛后 ...
- 2019HDU多校赛第二场 H HDU 6598 Harmonious Army(最小割模型)
参考博客https://blog.csdn.net/u013534123/article/details/97142191 #include<bits/stdc++.h> using na ...
- HDU6602 Longest Subarray hdu多校第二场 线段树
HDU6602 Longest Subarray 线段树 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6602 题意: 给你一段区间,让你求最长的区间使 ...
- hdu多校第二场 1005 (hdu6595) Everything Is Generated In Equal Probability
题意: 给定一个N,随机从[1,N]里产生一个n,然后随机产生一个n个数的全排列,求出n的逆序数对的数量,加到cnt里,然后随机地取出这个全排列中的一个非连续子序列(注意这个子序列可以是原序列),再求 ...
- hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash
题意: 找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串 输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数 题解: (回文自动机和回文树是一个东西) 首先用回文 ...
- hdu多校第二场1011 (hdu6601) Keen On Everything But Triangle 主席树
题意: 给定一个数列,每次询问一个区间,问这个区间中的值可组成的周长最大的三角形的周长. 题解: 定理1:给定一些值,这些值中组成边长最大的三角形的三条边的大小排名一定是连续的. 证明:假如第k大,第 ...
- hdu多校第二场 1010 (hdu6600)Just Skip This Problem
题意: 给你一个数x,允许你多次询问yi,然后回答你x xor yi 是否等于yi,询问尽量少的次数以保证能求出xi是几,求出这样询问次数最少的询问方案数. 结果mod1e6+3 题解: 队友赛时很快 ...
随机推荐
- Centos7 -samba服务配置
Centos7 -samba服务配置 https://blog.csdn.net/zh515858237/article/details/76914905 http://blog.51cto.com/ ...
- VMware下Linux构建仅主机模式的局域网网络配置方案
最近使用Linux,进行网络配置,以前都是桥接直连,然后直接组网.由于一些原因现在虚拟机做内网使用,不用上网,只能使用仅主机模式.在仅主机模式下进行虚拟机组网. 仅主机模式下各个虚拟机只能和主机通信, ...
- [2019杭电多校第二场][hdu6601]Keen On Everything But Triangle
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6601 题意是说用给定区间内的数字组成周长最大的三角形. 大致做法就是求区间第1大,第2大和第3大然后判 ...
- XE2再次安装JVCL
说再次安装,是因为我忘了自己之前写过的方法,装完之后感觉怪怪的,想看看别人是怎么装的,于是用google搜索了一下,才发现之前写过: http://www.cnblogs.com/findumars/ ...
- grunt默认只允许localhost和访问,如何设置外部IP地址访问
转载请注明出处: 猩猩队长 http://www.cnblogs.com/wayns/p/access_grunt_server_from_outside.html 使用Yeoman生成器创建web ...
- Vue.js——60分钟组件快速入门(上篇)二
来源:https://www.cnblogs.com/keepfool/p/5625583.html 组件简介 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小 ...
- 《快学scala》读书笔记(2)
第二章 控制结构和函数 1.条件表达式 (1)scala中if/else表达式有值,这个值就是跟在if或者else之后的表达式的值.如: if (x > 0) 1 else -1 这个表达式的 ...
- Vue简单封装axios—解决post请求后端接收不到参数问题
1.在src/下新建api文件夹,api/下新建index.js和public.js 在public.js中: import axios from 'axios'; import qs from 'q ...
- 行人重识别(ReID) ——基于深度学习的行人重识别研究综述
转自:https://zhuanlan.zhihu.com/p/31921944 前言:行人重识别(Person Re-identification)也称行人再识别,本文简称为ReID,是利用计算机视 ...
- linux 服务器与客户端异常断开连接问题
服务器与客户端连接,客户端异常断掉之后服务器端口仍然被占用, 到最后是不是服务器端达到最大连接数就没法连接了?领导让我测试这种情况,我用自己的电脑当TCP Client,虚拟机当服务器,连接之后能正常 ...