[bzoj3158]千钧一发——二分图+网络流
题目
题解
很容易建立模型,如果两个点不能匹配,那么连一条边,那么问题就转化为了求一个图上的最大点权独立集。
而我们可以知道:
最大点权独立集+最小点权覆盖集=总权值。
同时最小点权覆盖在一般图上是np的,但是在二分图上就是可解的。
利用一系列数学性质,可以证明A[i]与A[j]奇偶性不同是ij之间连边的充分必要条件。
详细见lidaxin的博客
那么我们可以跑一边最大流即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1005;
const ll inf = 100000000000000;
ll N, A[maxn], B[maxn];
ll mx = 0;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
bool ok(ll a, ll b) {
ll sq = a * a + b * b;
ll t = sqrt(sq);
if (sq != (t * t))
return false;
if (gcd(a, b) > 1)
return false;
return true;
}
struct edge {
ll from;
ll to;
ll cap;
};
vector<edge> edges;
vector<int> G[maxn];
ll s, t, v, ans;
ll dist[maxn], iter[maxn];
void add_edge(int from, int to, ll cap) {
edges.push_back((edge){from, to, cap});
edges.push_back((edge){to, from, 0});
int m = edges.size();
G[from].push_back(m - 2);
G[to].push_back(m - 1);
}
void bfs(int s) {
memset(dist, -1, sizeof(dist));
queue<int> q;
q.push(s);
dist[s] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = 0; i < G[u].size(); i++) {
edge &e = edges[G[u][i]];
if (e.cap > 0 && dist[e.to] == -1) {
dist[e.to] = dist[u] + e.cap;
q.push(e.to);
}
}
}
}
ll dfs(ll s, ll t, ll flow) {
if (s == t)
return flow;
for (ll &i = iter[s]; i < G[s].size(); i++) {
edge &e = edges[G[s][i]];
if (e.cap > 0 && dist[e.to] > dist[s]) {
ll d = dfs(e.to, t, min(flow, e.cap));
if (d > 0) {
e.cap -= d;
edges[G[s][i] ^ 1].cap += d;
return d;
}
}
}
return 0;
}
ll dinic(int s, int t) {
ll flow = 0;
while (1) {
bfs(s);
if (dist[t] == -1)
return flow;
memset(iter, 0, sizeof(iter));
ll f;
while ((f = dfs(s, t, inf)) > 0)
flow += f;
}
}
int main() {
// freopen("input.b", "r", stdin);
ans = 0;
scanf("%lld", &N);
for (int i = 1; i <= N; i++) {
scanf("%lld", &A[i]);
}
for (int i = 1; i <= N; i++) {
scanf("%lld", &B[i]);
ans += B[i];
}
// s:0, t:N+1
s = 0, t = N + 1, v = t + 1;
for (int i = 1; i <= N; i++) {
if (A[i] & 1)
add_edge(s, i, B[i]);
else
add_edge(i, t, B[i]);
if (A[i] & 1)
for (int j = 1; j <= N; j++) {
if (!(A[j] & 1))
if (ok(A[i], A[j]))
add_edge(i, j, inf);
}
}
ans -= dinic(s, t);
printf("%lld", ans);
}
[bzoj3158]千钧一发——二分图+网络流的更多相关文章
- 二分图&网络流&最小割等问题的总结
二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 技巧: 1.拆点为边,即一个点有限制,可将其转化为边 BZOJ1066, ...
- hdu1569-方格取数-二分图网络流
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- BZOJ3158 千钧一发(最小割)
可以看做一些物品中某些互相排斥求最大价值.如果这是个二分图的话,就很容易用最小割了. 观察其给出的条件间是否有什么联系.如果两个数都是偶数,显然满足条件二:而若都是奇数,则满足条件一,因为式子列出来发 ...
- 【洛谷】4304:[TJOI2013]攻击装置【最大点独立集】【二分图】2172: [国家集训队]部落战争【二分图/网络流】【最小路径覆盖】
P4304 [TJOI2013]攻击装置 题目描述 给定一个01矩阵,其中你可以在0的位置放置攻击装置. 每一个攻击装置(x,y)都可以按照“日”字攻击其周围的8个位置(x-1,y-2),(x-2,y ...
- 「SDFZ听课笔记」二分图&&网络流
二分图? 不存在奇环(长度为奇数的环)的图 节点能黑白染色,使得不存在同色图相连的图 这两个定义是等价哒. 直观而言,就是这样的图: 二分图有一些神奇的性质,让一些在一般图上复杂度飞天的问题可以在正常 ...
- 洛谷 P2756 飞行员配对方案问题 (二分图/网络流,最佳匹配方案)
P2756 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其 ...
- 二分图&网络流初步
链接 : 最小割&网络流应用 EK太低级了,不用. 那么请看:#6068. 「2017 山东一轮集训 Day4」棋盘,不用EK你试试? dinic模板及部分变形应用见zzz大佬的博客:网络流学 ...
- BZOJ3158: 千钧一发
[传送门:BZOJ3158] 简要题意: 给出n个机器,每个机器有a[i]基础值和b[i]价值 选出一部分机器使得这些机器里面两两至少满足以下两种条件之一: 1.a[i]2+a[j]2!=T2(T为正 ...
- 暑假集训-二分图,网络流,2-SAT
匈牙利算法DFS bool dfs(int u){ ; i <= n; i++){ if(a[u][i] && !visit[i]){ visit[i] = true; || d ...
随机推荐
- django-mysqlclient_1193错误
Django 配置 mysqlclient 驱动 1193错误 错误描述: django.db.utils.OperationalError: (1193, "Unknown system ...
- python基础之内置函数补充、匿名函数、递归函数
内置函数补充 python divmod()函数:把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b) 语法: 1 divmod(a, b) #a.b为数字,a为除数 ...
- 19,Ubuntu安装之python开发
什么??公司要用Ubuntu(乌班图)?不会用??怎么进行python开发??? 乌班图操作系统下载地址:http://releases.ubuntu.com/18.04/ubuntu-18.04 ...
- Android开发——事件分发机制详解
0. 前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52566965 深入学习事件分发机制,是为了解决在Android开发中 ...
- Java从数据库读取页面树形菜单
从数据库加载菜单及子菜单主要使用递归的方法,具体实现可看代码 首先封装一个菜单pojo public class Menu { // 菜单id private String id; // 菜单名称 p ...
- 如何在一个顶级域名下用两个二级域名访问vps下的两个项目网站--完美解决骗
本人是原址是http://www.webzhe.com/server/340 后经过本人的实践修改,增加截图,等具体的步骤,完美解决 如何在vps中设置二级域名开通子网站,这个问题涉及到两步:一首先要 ...
- Linux命令学习总结(一)
命令 -选项 参数 如果选项是一个单词时,选项前面要加2个- modprobe -r pcspkr 在终端中输入的时候有声音,可以用这个命令屏蔽声音 ,需要root权限 useradd userd ...
- linux ubuntu 现在显示的是ubuntu login
linux ubuntu 现在显示的是ubuntu login 如果要进图形界面,你需要安装桌面管理器sudo apt-get install ubuntu-desktop或sudo apt-get ...
- 【java下午茶】12306的双人票
明天下午就要和客户谈需求了,今天还在列车上假象着明天的情景,由于这是一个旅游的项目,所以想尽可能设计得人性化一些. 不过有件很不爽的事情就是和老公的位子是分开的,虽然我们订的是连坐号.就这个问题也是我 ...
- FluentAPI深入
1. HasMaxLenght 设定字段得最大长度: static void Main(string[] args) { using (TestDbContext ctx = new TestDbC ...