3158: 千钧一发

题目:传送门

题解:

   这是一道很好的题啊...极力推荐

   细看题目:要求一个最大价值,那么我们可以转换成求损失的价值最小

   那很明显就是最小割的经典题目啊?!

   但是这里两个子集的分化并不明显...GG

   耐心一点,从题目的要求再入手:

   对于第二个要求,如果两点的a值都为偶数,那么肯定满足

   那如果两个数都为奇数的话,也必定满足要求一,证明如下:

   1、一个奇数的平方%4为1,一个偶数的平方%4为0

   2、两个奇数的平方和%4为2

   3、如果两个奇数的平方和是一个奇数的平方,那么%4应该为1,不符合

   4、如果两个奇数的平方和是一个偶数的平方,那么%4应该为0,不符合

   因此得证。

   这样子思考的话,两个子集的分化就较为明显了:

   st向a值为奇数的相连,a值为偶数的向ed相连,容量都为b值;这样子所形成的两个子集里面的点一定都是符合要求的。

   最后一步,也是最关键的一步:

   两个子集之间两两匹配,如果当前匹配的两个点是不符合要求的,就将这两个点相连,容量为无限大。

   有什么用呢?自己画几个图便很容易理解:

   这时候我们跑最小割的话,割出来的边就是损失价值的最小值

   用sum-最小割就是答案啊

代码:

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define qread(x) x=read()
using namespace std;
typedef long long LL;
const LL inf=;
LL n,st,ed,sum;
LL A[],B[];
inline LL read()
{
LL f=,x=;char ch;
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return f*x;
}
struct node
{
LL x,y,c,next,other;
}a[];LL len,last[];
void ins(LL x,LL y,LL c)
{
int k1,k2;
k1=++len;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len; k2=++len;
a[len].x=y;a[len].y=x;a[len].c=;
a[len].next=last[y];last[y]=len; a[k1].other=k2;
a[k2].other=k1;
}
LL list[],h[],head,tail;
bool bt_h()
{
memset(h,,sizeof(h));h[st]=;
list[]=st;head=;tail=;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]== && a[k].c)
{
h[y]=h[x]+;
list[tail++]=y;
}
}
head++;
}
if(h[ed])return true;
return false;
}
LL find_flow(LL x,LL flow)
{
if(x==ed)return flow;
LL s=,t;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]==h[x]+ && a[k].c> && flow>s)
{
s+=t=find_flow(y,min(a[k].c,flow-s));
a[k].c-=t;a[a[k].other].c+=t;
}
}
if(s==)h[x]=;
return s;
}
LL gcd(LL a,LL b)
{
return a==?b:gcd(b%a,a);
}
bool pd(LL x,LL y)
{
LL T=x*x+y*y,t=sqrt(T);
if(t*t!=T)return true;
if(gcd(x,y)>)return true;
return false;
}
int main()
{
sum=;
qread(n);
len=;memset(last,,sizeof(last));
for(int i=;i<=n;i++)qread(A[i]);
for(int i=;i<=n;i++){qread(B[i]);sum+=B[i];}
st=n+;ed=st+;
for(int i=;i<=n;i++)
{
if(A[i]%==)ins(st,i,B[i]);
else ins(i,ed,B[i]);
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if((A[i]%==) && (A[j]%==) && !pd(A[i],A[j]))
ins(i,j,inf);
LL ans=;
while(bt_h())ans+=find_flow(st,inf);
printf("%lld\n",sum-ans);
return ;
}

bzoj3158&3275: 千钧一发(最小割)的更多相关文章

  1. 【BZOJ3158】千钧一发 最小割

    [BZOJ3158]千钧一发 Description Input 第一行一个正整数N. 第二行共包括N个正整数,第 个正整数表示Ai. 第三行共包括N个正整数,第 个正整数表示Bi. Output 共 ...

  2. 【BZOJ-3275&3158】Number&千钧一发 最小割

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 748  Solved: 316[Submit][Status][Discus ...

  3. bzoj 3158 千钧一发 —— 最小割

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3158 \( a[i] \) 是奇数则满足条件1,是偶数则显然满足条件2: 因为如果把两个奇数 ...

  4. BZOJ 3158 千钧一发 最小割

    分析: 偶数对满足条件2,所有奇数对满足条件1. 如果你能一眼看出这个规律,这道题就完成了一半. 我们只需要将数分为两类,a值为奇数,就从S向这个点连容量为b值的边,a值为偶数,就从这个点向T连容量为 ...

  5. BZOJ 3275: Number( 最小割 )

    S->每个奇数,每个偶数->T各连一条边, 容量为这个数字.然后不能同时选的两个数连容量为+oo的边. 总数-最大流即是答案. 因为满足a2+b2=c2的a,b一定是一奇一偶或者两个偶数, ...

  6. BZOJ3158 千钧一发(最小割)

    可以看做一些物品中某些互相排斥求最大价值.如果这是个二分图的话,就很容易用最小割了. 观察其给出的条件间是否有什么联系.如果两个数都是偶数,显然满足条件二:而若都是奇数,则满足条件一,因为式子列出来发 ...

  7. bzoj 3158 千钧一发(最小割)

    3158: 千钧一发 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 767  Solved: 290[Submit][Status][Discuss] ...

  8. bzoj 3275 Number(最小割)

    [题意] 给定n个数,要求选出一些数满足 1.存在c,a*a+b*b=c*c 2.gcd(a,b)=1  使得和最大. [思路] 二分图的最大权独立集(可以这么叫么QAQ 先拆点,对于不满足条件的两个 ...

  9. 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) \)里面这个一定不是平方数因为除二后是 ...

随机推荐

  1. Ubuntu 常用快捷键

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50285313 1 桌面 快捷键 作用 ...

  2. static方法调用

    Static方法调用,类名.方法名 int number = Integer.ParseInt(String ); 将字符串参数作为有符号的十进制整数进行解析 将数字解析成字节数组 Character ...

  3. WinServer-IIS-Dynamic IP Restrictions

    动态IP限制 来自为知笔记(Wiz)

  4. Linux - Redmine使用方式 | SVN提交代码

    Redmine使用方式 | SVN提交代码 本文地址:http://blog.csdn.net/caroline_wendy RbTools 1. 安装: svn co https://dev.cxx ...

  5. python设计模式 之 简单工厂模式

    简单工厂模式属于类的创建型模式,适合用来对大量具有共同接口的类进行实例化,它能够推迟到执行的时候才动态决定要创建哪个类的实例.而不是在编译时就必须知道要实例化哪个类. python: #!/usr/b ...

  6. 15-11-23:system指令

    CMD命令:开始->运行->键入cmd或command(在命令行里可以看到系统版本.文件系统版本) 1. appwiz.cpl:程序和功能 2. calc:启动计算器 3. certmgr ...

  7. android实现自动安装

    安装: String str = "/CanavaCancel.apk"; String fileName = Environment.getExternalStorageDire ...

  8. Linux换行符相关

    Linux和windows中的换行符差异问题LINUX的换行符在Windows记事本打开不换行或出现黑点是由于Linux和windows中的换行符差异问题造成的. Unix系统里,每行结尾只有“< ...

  9. python网页问题

    #django-admin不是个命令 添加环境变量 D:\Python36\Scripts #localhost加载失败 命令行 python manage.py runserver 0.0.0.0: ...

  10. 阿里巴巴和印度最大移动支付和商务平台Paytm

    2015年9月29日,阿里巴巴和印度最大移动支付和商务平台Paytm发布联合声明,宣布阿里巴巴集团及其旗下金融子公司蚂蚁金服将向Paytm注入新资金.阿里称这是一项“战略性的”投资. 蚂蚁金服已经在2 ...