[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 ...
随机推荐
- angular-file-upload封装为指令+图片尺寸限制
不了解angular-file-upload基础使用 请先参考http://blog.csdn.net/lai_xu/article/details/49535847 博客地址 下文如果有更好的建议请 ...
- bzoj 4596 [Shoi2016]黑暗前的幻想乡 矩阵树定理+容斥
4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 559 Solved: 325[Submit][Sta ...
- maven使用jstl表达式和The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application解决
maven 中使用jstl表达式中出现如上错误.原因: 1.由于在maven中的web项目没有自动依赖jstl的jar 未在pom文件中添加jstl相关的jar <!--jstl表达式--> ...
- Shell脚本的颜色样式及属性控制
首先看一下格式 echo -e "\033[字背景颜色:文字颜色m字符串\033[0m" 举例 echo -e "\033[41;36m 字体 \033[0m" ...
- Unicode字符集,各个语言的区间
链接:http://www.cnblogs.com/zl0372/p/unicode.html 链接:http://www.unicode.org/ 链接:https://zh.wikipedia.o ...
- UVA - 10118 Free Candies 记忆化搜索经典
思路:d[a][b][c][d]表示从已经第一个篮子取了a颗糖,第二个取了b颗糖,第三个取了c颗糖,第四个取了d颗糖最多还能够获得多少糖果.首先明白一个问题:如果能分别取a,b,c,d个,不论如何取, ...
- ThreadLoacl,InheritableThreadLocal,原理,以及配合线程池使用的一些坑
虽然使用AOP可以获取方法签名,但是如果要获取方法中计算得出的数据,那么就得使用ThreadLocal,如果还涉及父线程,那么可以选择InheritableThreadLocal. 注意:理解一些原理 ...
- Linux分区和挂载(mount命令的学习)
当Windows系统出现问题的时候,可能需要重装系统,这个时候我们往往会使用系统盘将系统重新安装在C盘上,其他盘上的文件都没有受到重装系统的影 响,这就是分区的好处之一.同样,在Linux中也需要分区 ...
- 利用ffmpeg做视频解码的顺序
这几天在实验室捣鼓着用ffmpeg做视频解码,终于把数据解出来了,虽然还没有做显示部分,不知道解码解得对不对,但料想是不会有什么问题了.回头看看这几天的工作,其间也遇到了不少问题,主要还是对ffmpe ...
- Android安全开发之WebView中的大坑
0X01 About WebView 在Android开发中,经常会使用WebView来实现WEB页面的展示,在Activiry中启动自己的浏览器,或者简单的展示一些在线内容等.WebView功能强大 ...