[BZOJ3275] Number (网络流)
Description
有N个正整数,需要从中选出一些数,使这些数的和最大。
若两个数a,b同时满足以下条件,则a,b不能同时被选
1:存在正整数C,使a*a+b*b=c*c
2:gcd(a,b)=1
Input
Output
Sample Input
3 4 5 6 7
Sample Output
HINT
n<=3000。
Source
Solution
所以这道题a的数据范围是什么......用long long可以过,不知道int行不行。
嗯,把所有有关系的数字连一条边,这道题就变成了选出一些点使这些点两两没有边相连,求最大点权。这样就变成了最大点权独立集问题。
然后好像这个图一定是二分图,就可以用网络流做了。如果不是二分图就是NP问题了233。
有一个奇怪的定理:最大点权独立集 = 总权值 - 最小点权覆盖集 = 总权值 - 最小割 = 总权值 - 最大流。
好像不只一个定理,怪我咯。
把每个数字拆成两个点,从源点连向一个点,另一个点连向汇点,边权均为数字大小。然后把有关系的点之间连一条边,边权无限大。
跑一遍最大流,答案就是总权值 - 最大流 / 2。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = ;
struct edge
{
int v, nxt;
ll w;
}e[];
queue<int> Q;
ll d[];
int fst[], etot = , sss, ttt, level[]; void addedge(int u, int v, ll w)
{
e[++etot] = (edge){v, fst[u], w}, fst[u] = etot;
} bool istri(ll a, ll b)
{
ll c = (ll)sqrt(a * a + b * b + 0.1);
return c * c == a * a + b * b;
} ll gcd(ll a, ll b)
{
return b ? gcd(b, a % b) : a;
} int BFS()
{
memset(level, , sizeof(level));
Q.push(sss), level[sss] = ;
while(!Q.empty())
{
int u = Q.front();
Q.pop();
for(int i = fst[u]; i; i = e[i].nxt)
if(!level[e[i].v] && e[i].w)
Q.push(e[i].v), level[e[i].v] = level[u] + ;
}
return level[ttt];
} ll Dinic(int u, ll lim)
{
ll tmp = lim;
if(u == ttt) return lim;
for(int i = fst[u]; i; i = e[i].nxt)
if(level[e[i].v] == level[u] + && e[i].w)
{
ll flow = Dinic(e[i].v, min(tmp, e[i].w));
e[i].w -= flow, e[i ^ ].w += flow;
if(!(tmp -= flow)) break;
}
if(tmp == lim) level[u] = ;
return lim - tmp;
} int main()
{
int n;
ll ans = ;
cin >> n;
sss = (n << ) + , ttt = (n << ) + ;
for(int i = ; i <= n; i++)
cin >> d[i];
for(int i = ; i <= n; i++)
{
addedge(sss, i, d[i]), addedge(i, sss, );
addedge(i + n, ttt, d[i]), addedge(ttt, i + n, );
}
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
if(istri(d[i], d[j]) && gcd(d[i], d[j]) == )
addedge(i, j + n, INF), addedge(j + n, i, );
while(BFS())
ans += Dinic(sss, INF);
ans = -(ans >> );
for(int i = ; i <= n; i++)
ans += d[i];
cout << ans << endl;
return ;
}
[BZOJ3275] Number (网络流)的更多相关文章
- [BZOJ3275]Number解题报告|网络流
Description 有N个正整数,需要从中选出一些数,使这些数的和最大.若两个数a,b同时满足以下条件,则a,b不能同时被选1:存在正整数C,使a*a+b*b=c*c2:gcd(a,b)=1 这道 ...
- bzoj3275: Number
最小割...然后推一下可知不能的情况必定为一奇一偶,于是s->奇->偶->t.跑最小割即可. #include<cstdio> #include<cstring&g ...
- bzoj3275: Number(最小割)
3275: Number 题目:传送门 题解: 双倍经验@bzoj3158 代码: #include<cstdio> #include<cstring> #include< ...
- 【最小割】【Dinic】bzoj3275 Number
每个点拆点,分别向源/汇连a[i]的边,满足条件的相互连INF的边,答案为sum-maxflow*2. 因为若有几个点不能同时被选,我们要贪心地选择其中和尽量大的部分,这可以由最小割来保证. #inc ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 【BZOJ-3275&3158】Number&千钧一发 最小割
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 748 Solved: 316[Submit][Status][Discus ...
- 【BZOJ3275】Number 最小割
[BZOJ3275]Number Description 有N个正整数,需要从中选出一些数,使这些数的和最大.若两个数a,b同时满足以下条件,则a,b不能同时被选1:存在正整数C,使a*a+b*b=c ...
- 【POJ2699】The Maximum Number of Strong Kings(网络流)
Description A tournament can be represented by a complete graph in which each vertex denotes a playe ...
- POJ 2699 The Maximum Number of Strong Kings ——网络流
一定存在一种最优方案,使得分数前几个人是SK 所以我们可以二分答案或者枚举,然后就是经典的网络流建模. 另:输入很Excited #include <cstdio> #include &l ...
随机推荐
- System.in实现数据的键盘输入
System.in The "standard" input stream. This stream is already open and ready to supply inp ...
- php正则判断字符串是否含有中文
<?php $str = '若你安好便是晴天'; if (preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $str)>0) { echo '全是中文'; } ...
- python 两个list 求交集,并集,差集
def diff(listA,listB): #求交集的两种方式 retA = [i for i in listA if i in listB] retB = list(set(listA).inte ...
- web自动化一(selenium+python+pycharm环境搭建)
年前公司刚刚搭起了web自动化测试框架的环境,趁着过完年还没全部忘掉,准备把如何搭建环境的方法和大家分享下,有哪里不对的地方,请批评指正,共同进步,共勉! 为此我把搭建环境所需的软件打包上传到百度云, ...
- Java经典编程题50道之二
判断101-200之间有多少个素数,并输出所有素数. public class Example02 { public static void main(String[] args) { ...
- 从flexible.js引入高德地图谈起的移动端适配
曾几何时,前端还仅仅是PC端的.随着移动时代的兴起,h5及css3的推陈出新.前端的领域慢慢的由传统的pc端转入了移动端,这也导致了前端这一职业在风口的一段时间出尽了风头. 从开始的惶恐和无从下手,慢 ...
- 02 浅析Spring的AOP(面向切面编程)
1.关于AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.O ...
- python-scrapy的编码问题
在学习scrapy中,遇到编码问题还是很头痛的问题的.由于对于语言的对不熟悉,加上不会思考的去解决问题.这样盲目的实践似乎就是在浪费时间. 用心思考一下是非常重要的一个过程,在没有办法前进的时候,先学 ...
- 微信小程序--TabBar不出现的一种原因
转自 http://blog.csdn.net/yedouble/article/details/54089825 pages数组的第一项必须是tabBar的list数组的一员. quedian无法返 ...
- 腾讯云+校园扶持计划是bug还是福利
前言 上午突然收到好友的微信消息.打开一看是关于关腾讯云"云+校园扶持计划".仔细看下了意思就是用户可以花360大洋购买腾讯云服务器配置为1核2G,1M带宽的服务器3年.(腾讯 ...