bzoj 3158 千钧一发——网络流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3158
发现偶数之间一定满足第二个条件;奇数之间一定满足第一个条件 ( \( (2m+1)^{2}+(2n+1)^{2}=4m^{2}+4m+1+4n^{2}+4n+1 \),这是个偶数,所以 T2 的 T 一定是偶数;偶数的平方一定是4的倍数,不能有那个 +2 )。
所以如果把不合法的连起来,就是一个二分图。可以用最小割做,不合法之间的连边是 INF 这样。
注意判断第一个条件的时候不用在 12~1414222 之间二分(虽然时间和 gcd 时间一样),只需要求一下根号看看是不是整数就行了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int N=,M=,K=1e6+,Lm=,INF=1e9+;
int n,a[N],b[N],hd[N],xnt=,cur[N],nxt[M],to[M],cap[M];
int dfn[N],q[N],he,tl; ll s[N];
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
int gcd(int a,int b){return b?gcd(b,a%b):a;}
ll Sqr(int x){return (ll)x*x;}
void add(int x,int y,int z)
{
to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;cap[xnt]=z;
to[++xnt]=x;nxt[xnt]=hd[y];hd[y]=xnt;cap[xnt]=;
}
bool chk(ll x)
{
ll k=sqrt(x);
return k*k!=x;//!=
}
bool bfs()
{
memset(dfn,,sizeof dfn);dfn[]=;
q[he=tl=]=;
while(he<=tl)
{
int k=q[he++];
for(int i=hd[k],v;i;i=nxt[i])
if(cap[i]&&!dfn[v=to[i]])
dfn[v]=dfn[k]+,q[++tl]=v;
}
return dfn[n+];
}
int dinic(int cr,int flow)
{
if(cr==n+)return flow;
int use=;
for(int& i=cur[cr],v;i;i=nxt[i])
if(cap[i]&&dfn[v=to[i]]==dfn[cr]+)
{
int tmp=dinic(v,Mn(flow-use,cap[i]));
if(!tmp)dfn[v]=;
use+=tmp;cap[i]-=tmp;cap[i^]+=tmp;
if(use==flow)return use;
}
return use;
}
int main()
{
scanf("%d",&n);int ans=;
for(int i=;i<=n;i++)scanf("%d",&a[i]),s[i]=Sqr(a[i]);
for(int i=;i<=n;i++)scanf("%d",&b[i]),ans+=b[i];
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
{
if(gcd(a[i],a[j])>||chk(s[i]+s[j]))continue;
a[i]&?add(i,j,INF):add(j,i,INF);
}
for(int i=;i<=n;i++)
if(a[i]&)add(,i,b[i]); else add(i,n+,b[i]);
while(bfs())memcpy(cur,hd,sizeof hd),ans-=dinic(,INF);
printf("%d\n",ans);
return ;
}
bzoj 3158 千钧一发——网络流的更多相关文章
- BZOJ 3158: 千钧一发
3158: 千钧一发 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1201 Solved: 446[Submit][Status][Discuss ...
- bzoj 3158 千钧一发(最小割)
3158: 千钧一发 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 767 Solved: 290[Submit][Status][Discuss] ...
- bzoj 3158 千钧一发 —— 最小割
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3158 \( a[i] \) 是奇数则满足条件1,是偶数则显然满足条件2: 因为如果把两个奇数 ...
- BZOJ 3158 千钧一发 (最大流->二分图带权最大独立集)
题面:BZOJ传送门 和方格取数问题很像啊 但这道题不能像网格那样黑白染色构造二分图,所以考虑拆点建出二分图 我们容易找出数之间的互斥关系,在不能同时选的两个点之间连一条流量为$inf$的边 由于我们 ...
- bzoj 3158: 千钧一发【最小割】
这个条件非常妙啊,奇数和奇数一定满足1,因为\( (2a+1)^2+(2b+1)^2=4a^2+4a+4b^2+4b+2=2(2(a^2+a+b^2+b)+1) \)里面这个一定不是平方数因为除二后是 ...
- BZOJ 3158 千钧一发 最小割
分析: 偶数对满足条件2,所有奇数对满足条件1. 如果你能一眼看出这个规律,这道题就完成了一半. 我们只需要将数分为两类,a值为奇数,就从S向这个点连容量为b值的边,a值为偶数,就从这个点向T连容量为 ...
- bzoj 1189 紧急疏散 网络流
二分答案,网络流判断 将每个门拆点,每个人连向每个门的dis~当前解 然后跑最大流,如果等于人数,即为可行解 #include<cstdio> #include<iostream&g ...
- BZOJ 2561 最小生成树 | 网络流 最小割
链接 BZOJ 2561 题解 用Kruskal算法的思路来考虑,边(u, v, L)可能出现在最小生成树上,就是说对于所有边权小于L的边,u和v不能连通,即求最小割: 对于最大生成树的情况也一样.容 ...
- BZOJ 1066 蜥蜴(网络流)
很普通的拆点网络流,把每个柱子拆成两个点(i,j,0)和(i,j,1).对于柱子的高度限制则加边((i,j,0),(i,j,1),height). 两个柱子能互相到达则加边((i,j,1),(i1,j ...
随机推荐
- js中常用的字符串方法
1,基础方法 charAt();返回该位置的字符,类似数组下标: substring();返回选中的字符,两个参数是下标. slice();参数是是一个正数,返回该数之后的剩余字符串:参数是负数,返回 ...
- iptables详解(14):iptables小结之常用套路
不知不觉,已经总结了13篇iptables文章,这些文章中有一些需要注意的地方. 此处,我们对前文中的一些注意点进行总结,我们可以理解为对"常用套路"的总结. 记住这些套路,能让我 ...
- 031——VUE中表单控件处理之使用vue控制input和textarea表单项
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- iOS TableView常见问题
Q:表视图只需要部分单元格,怎样删除下方多余的空白单元格? A:viewDidLoad中添加 self.tableView.tableFooterView=[[UIView alloc] init]; ...
- java中join用法
今天又把join的用法大概看了一下,其实理解起来,还是比较简单.用个简单的例子说明一下吧. 1.通过下面的例子,可以看到说出结果中首先全部是是Thread-1,之后才会是Thread-2,这是因为在主 ...
- 【dlbook】优化
[神经网络优化的挑战] 一.病态: 虽然学习率很小,而且梯度大,但是由于Hessian阵的病态,二次项比一次项还要大,梯度下降事实上并不一定能下降,反而有可能上升.因此需要将学习率调低. 表现:梯度很 ...
- dpkg: 处理归档 /var/cache/apt/archives/swig2.0_2.0.12-1ubuntu4_amd64.deb (--unpack)时出错:
问题: sudo apt-get upgrade 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 正在计算更新... 完成下列软件包的版本将保持不变: lib ...
- Android 你可能忽略的提高敲代码效率的方式
Android 你可能忽略的提高敲代码效率的方式
- 解决apt-get安装中的E: Sub-process /usr/bin/dpkg returned an error code (1)问题
在用apt-get安装软件包的时候遇到E: Sub-process /usr/bin/dpkg returned an error code (1)问题,解决方法如下: cd /var/lib/dpk ...
- Objective C----手动管理内存和自动管理内存
对象的引用计数(Reference Counting) 正常情况下,当一段代码需要访问某个对象时,该对象的引用的计数加1:当这段代码不再访问该对象时,该对象的引用计数减1,表示这段代码不再访问该对象: ...