3158: 千钧一发

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 767  Solved: 290
[Submit][Status][Discuss]

Description

 

Input

第一行一个正整数N。

第二行共包括N个正整数,第 个正整数表示Ai。

第三行共包括N个正整数,第 个正整数表示Bi。

Output

共一行,包括一个正整数,表示在合法的选择条件下,可以获得的能量值总和的最大值。

Sample Input

4
3 4 5 12
9 8 30 9

Sample Output

39

HINT

1<=N<=1000,1<=Ai,Bi<=10^6

Source

【思路】

最小割。

注意到ai,aj同时是偶数或同时是奇数时必定可以被同时选出:

1 同为偶数满足条件2

2 同为奇数时有(2a+1)^2+(2b+1)^2=2(2a^2+2b^2+2a+2b+1),所以满足条件1。

以此构二分图,设奇数为X结点偶数为Y结点,如果不满足任一条件则连边(Xi,Yj,INF),同时相应连S到X,Y到T的边容量为b,那么答案就是一个二分图最小割,即通过删除一些结点使得满足剩下的结点不相邻且有b之和最小。

【代码】

 #include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std; typedef long long LL;
const int maxn = +;
const int INF = 1e9+1e9; struct Edge{ int u,v,cap,flow;
}; struct Dinic {
int n,m,s,t;
int d[maxn],cur[maxn],vis[maxn];
vector<int> G[maxn];
vector<Edge> es; void init(int n) {
this->n=n;
for(int i=;i<n;i++) G[i].clear();
es.clear();
}
void AddEdge(int u,int v,int cap) {
es.push_back((Edge){u,v,cap,});
es.push_back((Edge){v,u,,});
m=es.size();
G[u].push_back(m-);
G[v].push_back(m-);
}
bool bfs() {
queue<int> q;
memset(vis,,sizeof(vis));
vis[s]=; d[s]=; q.push(s);
while(!q.empty()) {
int u=q.front(); q.pop();
for(int i=;i<G[u].size();i++) {
Edge &e=es[G[u][i]];
int v=e.v;
if(!vis[v] && e.cap>e.flow) {
vis[v]=;
d[v]=d[u]+;
q.push(v);
}
}
}
return vis[t];
}
int dfs(int u,int a) {
if(u==t || a==) return a;
int f,flow=;
for(int& i=cur[u];i<G[u].size();i++) {
Edge& e=es[G[u][i]];
int v=e.v;
if(d[v]==d[u]+ && (f=dfs(v,min(a,e.cap-e.flow)))>) {
e.flow+=f;
es[G[u][i]^].flow-=f;
flow+=f , a-=f;
if(!a) break;
}
}
return flow;
}
int maxflow(int s,int t) {
this->s=s , this->t=t;
int flow=;
while(bfs()) {
memset(cur,,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
} dc; int n;
int a[maxn],b[maxn]; bool issqr(LL x) { return sqrt(x)*sqrt(x) == x;
}
int gcd(int x,int y) {
return y==? x:gcd(y,x%y);
}
bool jud(LL x,LL y) {
LL t=x*x+y*y , sq=sqrt(t);
if(sq*sq!=t) return ;
if(gcd(x,y)>) return ;
return ;
} int main() {
scanf("%d",&n);
dc.init(n+);
int s=n,t=s+;
int ans=;
for(int i=;i<n;i++) scanf("%d",&a[i]);
for(int i=;i<n;i++) scanf("%d",&b[i]) , ans+=b[i];
for(int i=;i<n;i++)
if((a[i]&)) dc.AddEdge(s,i,b[i]);
else dc.AddEdge(i,t,b[i]);
for(int i=;i<n;i++) for(int j=;j<n;j++)
if((a[i]&) && (a[j]&)==)
if(!jud(a[i],a[j])) dc.AddEdge(i,j,INF);
ans-=dc.maxflow(s,t);
printf("%d",ans);
return ;
}

bzoj 3158 千钧一发(最小割)的更多相关文章

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

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

  2. BZOJ 3158 千钧一发 最小割

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

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

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

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

  5. BZOJ 3158: 千钧一发

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

  6. bzoj 3158 千钧一发——网络流

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3158 发现偶数之间一定满足第二个条件:奇数之间一定满足第一个条件 ( \( (2m+1)^{ ...

  7. spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】

    因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...

  8. BZOJ 3158 千钧一发 (最大流->二分图带权最大独立集)

    题面:BZOJ传送门 和方格取数问题很像啊 但这道题不能像网格那样黑白染色构造二分图,所以考虑拆点建出二分图 我们容易找出数之间的互斥关系,在不能同时选的两个点之间连一条流量为$inf$的边 由于我们 ...

  9. bzoj 2229 [Zjoi2011]最小割(分治+最小割)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2229 [题意] 回答若干个关于割不超过x的点对数目的询问. [思路] [最小割最多有n ...

随机推荐

  1. Android Cursor类的概念和用法

    http://www.2cto.com/kf/201109/103163.html 关于 Cursor 在你理解和使用 Android Cursor 的时候你必须先知道关于 Cursor 的几件事情: ...

  2. dnw for linux: Ubuntu下可用,无需编译驱动,mini2440可用

    1.安装所需库文件 sudo apt-get install libusb-dev 2.源代码如下 /* dnw2 linux main file. This depends on libusb. * ...

  3. GoogleAuthenticator

    <?php /** * PHP Class for handling Google Authenticator 2-factor authentication * * @author Micha ...

  4. iOS NSData简单解析

    iOS 基本数据类型之NSData 1 nsdata 作用: 用于存储二进制的数据类型 nadat类提供一种简单的方式,它用来设置缓存区.将文件的内容读入到缓存区.或者将缓存区中的内容写到一个文件. ...

  5. 在用VC编译下debug和release的什么区别

    DEBUG和RELEASE 版本差异及调试相关问题:.         内存分配问题 1.          变量未初始化.下面的程序在debug中运行的很好. thing * search(thin ...

  6. java编码转化方案-备用

    import java.io.UnsupportedEncodingException; /** * 转换字符串的编码 */ public class changeCharSet { /** 7位AS ...

  7. VB.NET中LINQ TO List泛型查询语句(分组,聚合函数)

    Public Class LinqToList 'LINQ在C#中使用比较方便,但是在VB中使用比较麻烦,复杂,和C#用法并不太一样 Dim listNew As List(Of Product) = ...

  8. 【Linux】常用命令

    一.文件结构     /:       根目录 /bin:    系统所需要的那些命令位于此目录. /boot:   Linux的内核及引导系统程序所需要的文件目录,GRUB或LILO系统引导管理器也 ...

  9. php数组基础

    一.php数组的声明      1.数组中可以有任意类型的数据      2.长度可以变长      3.数组的分类:           a.索引数组:数组是以从0开始的帧数作为索引值       ...

  10. frame,bounds,center-三者的含义

    frame与bounds的区别比较 frame,bounds,center-三者的含义 偶然觉的,这三个属性有时候定位的时候,需要用.于是就来搞清楚,到底frame,bounds,center 这三个 ...