BZOJ 3275: Number (二分图最小割)
题意
有nnn个数,其中同时满足下面两个条件的数对不能同时选,求选出一些数让和最大.
- 若两个数aaa,bbb同时满足以下条件,则aaa,bbb不能同时被选
- 存在正整数ccc,使a∗a+b∗b=c∗ca*a+b*b=c*ca∗a+b∗b=c∗c
- gcd(a,b)=1gcd(a,b)=1gcd(a,b)=1
分析
看到这熟悉二元关系,就能够用最小割做了.但是乍一看不是二分图的模型,就不能直接连了.所以有一种做法就是拆点.
但是我们看这两个式子可以推出来这的确是一个二分图,而且是奇偶二分图,证明如下:
- a,ba,ba,b不可能同为偶数,否则不满足gcd(a,b)=1gcd(a,b)=1gcd(a,b)=1
- a,ba,ba,b不可能同为奇数,证明为
- 假设存在a,ba,ba,b为奇数且c2=a2+b2c^2=a^2+b^2c2=a2+b2,那么ccc必为偶数,但是a2+b2≡2 (mod 4)a^2+b^2\equiv 2\ (mod\ 4)a2+b2≡2 (mod 4)而c2≡0 (mod 4)c^2\equiv 0\ (mod\ 4)c2≡0 (mod 4),矛盾
综上,存在矛盾的数对一定是奇偶性不同的数字,所以我们用二分图的方式,矛盾就连一条容量为∞\infty∞的边,然后SSS向奇数连容量为数值的边,偶数向TTT连容量为数值的边,最后用所有数的总和减去最小割就行了
CODE
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
template<typename T>inline void read(T &num) {
char ch; int flg=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flg=-flg;
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
num*=flg;
}
const int inf = 1e9;
const int MAXN = 3005;
const int MAXM = 20005;
int n, m, fir[MAXN], S, T, cnt;
struct edge { int to, nxt; int c; }e[MAXM];
inline void add(int u, int v, int cc) {
e[cnt] = (edge){ v, fir[u], cc }; fir[u] = cnt++;
e[cnt] = (edge){ u, fir[v], 0 }; fir[v] = cnt++;
}
int dis[MAXN], vis[MAXN], info[MAXN], cur, q[MAXN];
inline bool bfs() {
int head = 0, tail = 0;
vis[S] = ++cur; q[tail++] = S;
while(head < tail) {
int u = q[head++];
for(int i = fir[u]; ~i; i = e[i].nxt)
if(e[i].c && vis[e[i].to] != cur)
vis[e[i].to] = cur, dis[e[i].to] = dis[u] + 1, q[tail++] = e[i].to;
}
if(vis[T] == cur) memcpy(info, fir, (T+1)<<2);
return vis[T] == cur;
}
int dfs(int u, int Max) {
if(u == T || !Max) return Max;
int flow=0, delta;
for(int &i = info[u]; ~i; i = e[i].nxt)
if(e[i].c && dis[e[i].to] == dis[u] + 1 && (delta=dfs(e[i].to, min(e[i].c, Max-flow)))) {
e[i].c -= delta, e[i^1].c += delta, flow += delta;
if(flow == Max) return flow;
}
if(!flow) dis[u] = -1;
return flow;
}
inline int dinic() {
memset(vis, 0, sizeof vis);
int flow=0, x;
while(bfs()) {
while((x=dfs(S, inf))) flow+=x;
}
return flow;
}
int A[MAXN], sum;
int gcd(int x, int y) { return y ? gcd(y, x%y) : x; }
inline bool chk(int a,int b)
{
int s = a*a + b*b, q = int(sqrt(s));
if(q * q != s)return 0;
if(gcd(a, b) != 1)return 0; //先判勾股数再判gcd会快好几倍
return 1;
}
int main () {
read(n); S = 0; T = n+1;
memset(fir, -1, sizeof fir);
for(int i = 1; i <= n; ++i) {
read(A[i]); sum += A[i];
if(A[i]&1) add(S, i, A[i]);
else add(i, T, A[i]);
for(int j = 1; j < i; ++j)
if(chk(A[i], A[j])) {
if(A[i]&1) add(i, j, inf);
else add(j, i, inf);
}
}
printf("%d\n", sum-dinic());
}
BZOJ 3275: Number (二分图最小割)的更多相关文章
- bzoj 3275 Number(最小割)
[题意] 给定n个数,要求选出一些数满足 1.存在c,a*a+b*b=c*c 2.gcd(a,b)=1 使得和最大. [思路] 二分图的最大权独立集(可以这么叫么QAQ 先拆点,对于不满足条件的两个 ...
- bzoj 3275: Number (最小割)
题目的意思是要选一些数,但是这些数如果满足两个条件的话就不能一起被选. type arr=record toward,next,cap:longint; end; const maxn=; maxm= ...
- bzoj 3158 千钧一发(最小割)
3158: 千钧一发 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 767 Solved: 290[Submit][Status][Discuss] ...
- BZOJ 3275: Number( 最小割 )
S->每个奇数,每个偶数->T各连一条边, 容量为这个数字.然后不能同时选的两个数连容量为+oo的边. 总数-最大流即是答案. 因为满足a2+b2=c2的a,b一定是一奇一偶或者两个偶数, ...
- 【BZOJ-3275&3158】Number&千钧一发 最小割
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 748 Solved: 316[Submit][Status][Discus ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- [二分图&最小割]
OTL@assassain 反转源汇的模型: 给定一个二分图,同时选择集合中的两个点会有一个代价,选择每一个点有一个收益,问最大收益是多少 (即两个点在不同的集合中是有冲突关系的) 解法: 用最小割模 ...
- [BZOJ 2127] happiness 【最小割】
题目链接:BZOJ - 2127 题目分析 首先,每个人要么学文科,要么学理科,所以可以想到是一个最小割模型. 我们就确定一个人如果和 S 相连就是学文,如果和 T 相连就是学理. 那么我们再来确定建 ...
- BZOJ.3532.[SDOI2014]LIS(最小割ISAP 退流)
BZOJ 洛谷 \(LIS\)..经典模型? 令\(f_i\)表示以\(i\)结尾的\(LIS\)长度. 如果\(f_i=1\),连边\((S,i,INF)\):如果\(f_i=\max\limits ...
随机推荐
- 【转帖】Linux 内核系统架构
Linux 内核系统架构 描述Linux内核的文章已经有上亿字了 但是对于初学者,还是应该多学习多看,毕竟上亿字不能一下子就明白的. 即使看了所有的Linux 内核文章,估计也还不是很明白,这时候 ...
- Appium+unittest+python登录app
代码: # coding=utf-8 from appium import webdriver import time import unittest import os import HTMLTes ...
- Centos安装 k8s
### 一. 安装docker 1.安装依赖包```shellsudo yum install -y yum-utils device-mapper-persistent-data lvm2 ``` ...
- 笔记-10:处理时间的标准库-time库
1.time库介绍 主要用来处理时间的标准库. time库提供了系统级精确计时器的计时功能,可以用来分析程序性能,也可让程序暂停运行时间. time库的功能主要分为:时间处理.时间格式化.计时. 2. ...
- echarts配置项说明//持续添加
<template> <div> <!-- <h2>本月抄表完成率</h2> --> <!-- <div id=&qu ...
- SAS学习笔记13 SAS数据清洗和加工(续)
查找缺失值 cha[*]和num[*]是建立数组cha和num,但不指定数组中的元素数 自动变量_character_表示数据集中的所有字符型变量 自动变量_numeric_表示数据集中的所有数值型变 ...
- ckplayer获取播放时长一
<div id="a1"></div> <div id="nowTime"></div> <script ...
- hdu 6180贪心
题意:有m个工程,一台机器在同一时间只能运行一个工程,告诉你每个工程的起始时间和结束时间,求出最少要多少个机器以及最小的机器总运行时间(机器开始了就不能停了,直到用完该台机器才停止). 题解:由于这里 ...
- hdu 4504 dp问题 转化能力不够 对状态的转移也是不够
威威猫系列故事——篮球梦 Time Limit: 300/100 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total ...
- 奇妙的算法【6】-WY回文、树、最优化、卷积判断
1,判断一个十进制正整数的二进制数是否为回文 package com.cnblogs.mufasa.answer1; import java.util.Scanner; public class Ma ...