题解

这个图是个二分图,因为如果有一个奇环的话,我们会发现一个数变成另一个数要乘上个数不同的质数,显然不可能

然后我们发现这个不是求最大流,而是问一定价值的情况下最大流是多少,二分一个流量,加上一条边限流,然后求最小费用(其实是最大费用,把权值取反即可)是不是小于等于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」数字配对的更多相关文章

  1. 「SDOI2016」数字配对

    「SDOI2016」数字配对 题目大意 传送门 题解 \(a_i\) 是 \(a_j\) 的倍数,且 \(\frac{a_i}{a_j}\) 是一个质数,则将 \(a_i,a_j\) 质因数分解后,其 ...

  2. loj2031 「SDOI2016」数字配对

    跑最大费用最大流,注意到每次 spfa 出来的 cost 一定是越来越少的,啥时小于 \(0\) 了就停了吧. #include <iostream> #include <cstri ...

  3. loj#2128. 「HAOI2015」数字串拆分 矩阵乘法

    目录 题目链接 题解 代码 题目链接 loj#2128. 「HAOI2015」数字串拆分 题解 \(f(s)\)对于\(f(i) = \sum_{j = i - m}^{i - 1}f(j)\) 这个 ...

  4. [LOJ 2070] 「SDOI2016」平凡的骰子

    [LOJ 2070] 「SDOI2016」平凡的骰子 [题目链接] 链接 [题解] 原题求的是球面面积 可以理解为首先求多面体重心,然后算球面多边形的面积 求重心需要将多面体进行四面体剖分,从而计算出 ...

  5. LOJ#2070. 「SDOI2016」平凡的骰子(计算几何)

    题面 传送门 做一道题学一堆东西不管什么时候都是美好的体验呢-- 前置芝士 混合积 对于三个三维向量\(a,b,c\),定义它们的混合积为\((a\times b)\cdot c\),其中$\time ...

  6. loj#2013. 「SCOI2016」幸运数字 点分治/线性基

    题目链接 loj#2013. 「SCOI2016」幸运数字 题解 和树上路径有管...点分治吧 把询问挂到点上 求出重心后,求出重心到每个点路径上的数的线性基 对于重心为lca的合并寻味,否则标记下传 ...

  7. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  8. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

  9. LOJ #6432. 「PKUSC2018」真实排名(组合数)

    题面 LOJ #6432. 「PKUSC2018」真实排名 注意排名的定义 , 分数不小于他的选手数量 !!! 题解 有点坑的细节题 ... 思路很简单 , 把每个数分两种情况讨论一下了 . 假设它为 ...

随机推荐

  1. VS2015调用matlab Plot函数

    最近经常采用Matlab仿真,然后C语言实现,最后需要将计算结果使用Qt的qwt或者matlab中的plot函数绘图. 因此想借用matlab的plot函数接口,使用VS2015来编写信号处理代码,最 ...

  2. echarts地图扩展___自定义的svg图

    echarts的自定义地图 标签引入js文件 <script type="text/javascript" src="echarts/require.js" ...

  3. 3.Filter和interceptor的区别

    https://blog.csdn.net/qq_36411874/article/details/53996873

  4. bzoj千题计划153:bzoj2431: [HAOI2009]逆序对数列

    http://www.lydsy.com/JudgeOnline/problem.php?id=2431 dp[i][j] 表示i的排列,有j个逆序对的方案数 加入i+1,此时i+1是排列中最大的数, ...

  5. highCharts参数实例解释

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  6. 解析html与xhtml的神器——HTMLParser与SGMLParser

    有时候你要把抓回来的数据进行提取,过大篇幅的html标签,你若使用正则表达式进行匹配的话,显然是低效的,这时使用python的HTMLParser模块会显得非常方便.据说还有个比较好用的解析器叫:Be ...

  7. SHA-1(安全哈希算法实现)

    如题,不知道sha-1的自己百度吧. #include <iostream> #include <vector> //定义vector数组 #include <strin ...

  8. 微信小程序开发教程(七)逻辑层——.js详解

    逻辑层,是事务逻辑处理的地方.对于小程序而言,逻辑层就是.js脚本文件的集合.逻辑层将数据进行处理后发送给视图层,同时接收视图层的事件反馈. 微信小程序开发框架的逻辑层是由JavaScript编写.在 ...

  9. POJ 3468 A Simple Problem with Integers (区间更新+区间查询)

    题目链接 Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operation ...

  10. java浅复制与深使用接口实现

    1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...