【LOJ】#2031. 「SDOI2016」数字配对
题解
这个图是个二分图,因为如果有一个奇环的话,我们会发现一个数变成另一个数要乘上个数不同的质数,显然不可能
然后我们发现这个不是求最大流,而是问一定价值的情况下最大流是多少,二分一个流量,加上一条边限流,然后求最小费用(其实是最大费用,把权值取反即可)是不是小于等于0,再看流量有没有流满
代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
//#define ivorysi
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define mo 974711
#define MAXN 15005
#define RG register
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N;
int a[405],b[405],col[405];
int64 c[405],g[405][405];
bool vis[405],E[405][405];
int totflow;
int64 totval,pi1;
struct node {
int to,next,cap;
int64 val;
}Edge[500005];
int head[407],sumE,S,T;
void add(int u,int v,int c,int64 a) {
Edge[++sumE].to = v;Edge[sumE].next = head[u];
Edge[sumE].cap = c;Edge[sumE].val = a;
head[u] = sumE;
}
void addtwo(int u,int v,int c,int64 a) {
add(u,v,c,a);add(v,u,0,-a);
}
bool check(int x) {
if(x == 1) return false;
for(int i = 2 ; i <= x / i ; ++i) {
if(x % i == 0) return false;
}
return true;
}
void dfs(int u,int id) {
vis[u] = 1;
col[u] = id;
for(int v = 1 ; v <= N ; ++v) {
int s = a[u],t = a[v];
if(s < t) swap(s,t);
if(s % t == 0 && check(s / t)) {
g[u][v] = g[v][u] = -c[u] * c[v];
E[u][v] = E[v][u] = 1;
if(!vis[v]) dfs(v,id ^ 1);
}
}
}
int aug(int u,int C) {
if(u == T) {
totflow += C;
totval += pi1 * C;
return C;
}
int flow = 0;
vis[u] = 1;
for(int i = head[u] ; i ; i = Edge[i].next) {
int v = Edge[i].to;
if(Edge[i].cap && !vis[v] && Edge[i].val == 0) {
int t = aug(v,min(C - flow,Edge[i].cap));
flow += t;
Edge[i].cap -= t;
Edge[i ^ 1].cap += t;
if(flow == C) return flow;
}
}
return flow;
}
bool modlabel() {
int64 d = 1e18;
for(int i = 1 ; i <= T ; ++i) {
if(vis[i]) {
for(int j = head[i] ; j ; j = Edge[j].next) {
int v = Edge[j].to;
if(Edge[j].cap && !vis[v] && Edge[j].val < d)
d = Edge[j].val;
}
}
}
if(d == 1e18) return false;
pi1 += d;
for(int i = 1 ; i <= T ; ++i) {
if(vis[i]) {
for(int j = head[i] ; j ; j = Edge[j].next) {
Edge[j].val -= d;
Edge[j ^ 1].val += d;
}
}
}
return true;
}
bool check_flow(int MID) {
memset(head,0,sizeof(head));sumE = 1;
totval = 0;totflow = 0;pi1 = 0;
for(int i = 1 ; i <= N ; ++i) {
if(!col[i]) addtwo(N + 1,i,b[i],0);
else addtwo(i,T,b[i],0);
}
for(int i = 1 ; i <= N ; ++i) {
if(!col[i]) {
for(int j = 1 ; j <= N ; ++j) {
if(col[j] && E[i][j]) {
addtwo(i,j,0x7fffffff,g[i][j]);
}
}
}
}
addtwo(S,N + 1,MID,0);
do {
do{
memset(vis,0,sizeof(vis));
}while(aug(S,0x7fffffff));
}while(modlabel());
return totflow >= MID && totval <= 0;
}
void Init() {
read(N);
for(int i = 1 ; i <= N ; ++i) read(a[i]);
for(int i = 1 ; i <= N ; ++i) read(b[i]);
for(int i = 1 ; i <= N ; ++i) read(c[i]);
for(int i = 1 ; i <= N ; ++i)
if(!vis[i]) dfs(i,0);
S = N + 2;T = N + 3;
}
void Solve() {
int L = 0,R = 0;
for(int i = 1 ; i <= N ; ++i) R += b[i];
R /= 2;
while(L < R) {
int mid = (L + R + 1) >> 1;
if(check_flow(mid)) L = mid;
else R = mid - 1;
}
out(L);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
return 0;
}
【LOJ】#2031. 「SDOI2016」数字配对的更多相关文章
- 「SDOI2016」数字配对
「SDOI2016」数字配对 题目大意 传送门 题解 \(a_i\) 是 \(a_j\) 的倍数,且 \(\frac{a_i}{a_j}\) 是一个质数,则将 \(a_i,a_j\) 质因数分解后,其 ...
- loj2031 「SDOI2016」数字配对
跑最大费用最大流,注意到每次 spfa 出来的 cost 一定是越来越少的,啥时小于 \(0\) 了就停了吧. #include <iostream> #include <cstri ...
- loj#2128. 「HAOI2015」数字串拆分 矩阵乘法
目录 题目链接 题解 代码 题目链接 loj#2128. 「HAOI2015」数字串拆分 题解 \(f(s)\)对于\(f(i) = \sum_{j = i - m}^{i - 1}f(j)\) 这个 ...
- [LOJ 2070] 「SDOI2016」平凡的骰子
[LOJ 2070] 「SDOI2016」平凡的骰子 [题目链接] 链接 [题解] 原题求的是球面面积 可以理解为首先求多面体重心,然后算球面多边形的面积 求重心需要将多面体进行四面体剖分,从而计算出 ...
- LOJ#2070. 「SDOI2016」平凡的骰子(计算几何)
题面 传送门 做一道题学一堆东西不管什么时候都是美好的体验呢-- 前置芝士 混合积 对于三个三维向量\(a,b,c\),定义它们的混合积为\((a\times b)\cdot c\),其中$\time ...
- loj#2013. 「SCOI2016」幸运数字 点分治/线性基
题目链接 loj#2013. 「SCOI2016」幸运数字 题解 和树上路径有管...点分治吧 把询问挂到点上 求出重心后,求出重心到每个点路径上的数的线性基 对于重心为lca的合并寻味,否则标记下传 ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
- Loj #3055. 「HNOI2019」JOJO
Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...
- LOJ #6432. 「PKUSC2018」真实排名(组合数)
题面 LOJ #6432. 「PKUSC2018」真实排名 注意排名的定义 , 分数不小于他的选手数量 !!! 题解 有点坑的细节题 ... 思路很简单 , 把每个数分两种情况讨论一下了 . 假设它为 ...
随机推荐
- 《Spring实战》 1-2
第1章 Spring之旅 Spring容器 Spring中bean的生命周期 Spring框架中的模块 Spring Portfolio 第2章 装配Bean 自动化装配bean 通过Java代码装配 ...
- python---重点(设计模式)
前戏:设计模式简介 设计模式是面向对象设计的解决方案,是复用性程序设计的经验总结.(与语言无关,任何语言都可以实现设计模式) 设计模式根据使用目的的不同而分为创建型模式(Creational Patt ...
- 视音频数据处理入门:FLV封装格式解析
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- 流媒体技术学习笔记之(十六)H264编码profile & level控制
H.264有四种画质级别,分别是baseline, extended, main, high: 1.Baseline Profile:基本画质.支持I/P 帧,只支持无交错(Progressive)和 ...
- Tomcat设置编码问题
为了解决编码问题,在tomcat的server.xml文件中添加了useBodyEncodingForURI="true"配置,如下 <Connector port=&quo ...
- 【BZOJ】3453: tyvj 1858 XLkxc 拉格朗日插值(自然数幂和)
[题意]给定k<=123,a,n,d<=10^9,求: $$f(n)=\sum_{i=0}^{n}\sum_{j=1}^{a+id}\sum_{x=1}^{j}x^k$$ [算法]拉格朗日 ...
- CodeForces 816C 思维
On the way to school, Karen became fixated on the puzzle game on her phone! The game is played as fo ...
- EOJ Monthly 2019.2 (based on February Selection) F.方差
题目链接: https://acm.ecnu.edu.cn/contest/140/problem/F/ 题目: 思路: 因为方差是用来评估数据的离散程度的,因此最优的m个数一定是排序后连续的,所以我 ...
- [转]ubuntu16.04~qt 5.8无法输入中文
编译fcitx-qt需要cmake,安装cmake命令,如果已经安装,请略过. sudo apt-get install cmake 安装 fcitx-libs-dev sudo apt-get in ...
- 莫烦课程Batch Normalization 批标准化
for i in range(N_HIDDEN): # build hidden layers and BN layers input_size = 1 if i == 0 else 10 fc = ...