CF498C. Array and Operations [二分图]
CF498C. Array and Operations
题意:
给定一个长为 n 的数组,以及 m 对下标 (a, b) 且满足 a + b 为奇数,每次操作可以将同一组的两个数同时除以一个公约数
问最多能进行多少次操作
\]
根据奇偶性二分图定理此题必定考二分图
贪心,每次除一个质数
质数之间是独立的,可以分开考虑每一个质因子
建图:s -x中质因子p数量-> x -inf-> y -y中质因子p数量-> t
最大权匹配就是这个质因子能带来的最多操作数
注意质因子分解别写错了,最后判x>1
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#define fir first
#define sec second
using namespace std;
const int N = 105, inf = 1e9;
int n, m, a[N];
pair<int, int> b[N];
map<int, int> li[N];
set<int> s;
void fac(int p) {
int x = a[p], sx = sqrt(x) + 1; //printf("fac %d\n", a[p]);
for(int i=2; i<=sx; i++) if(x % i == 0) { //printf("iii %d\n", i);
int cnt = 0;
while(x%i == 0) cnt++, x/=i; //printf("x %d\n", x);
//li[p].push_back(make_pair(i, cnt));
li[p][i] = cnt;
s.insert(i);
}
if(x > 1) li[p][x] = 1, s.insert(x);
}
namespace mf {
int s, t;
struct edge {int v, ne, c, f;} e[1005];
int cnt=1, h[N];
void ins(int u, int v, int c) { //printf("ins %d %d %d\n", u, v, c);
e[++cnt] = (edge) {v, h[u], c, 0}; h[u] = cnt;
e[++cnt] = (edge) {u, h[v], 0, 0}; h[v] = cnt;
}
int cur[N], vis[N], d[N], head, tail, q[N];
bool bfs() {
memset(vis, 0, sizeof(vis));
head = tail = 1;
q[tail++] = s; d[s] = 0; vis[s] = 1;
while(head != tail) {
int u = q[head++];
for(int i=h[u]; i; i=e[i].ne) {
int v = e[i].v;
if(!vis[v] && e[i].c > e[i].f) {
vis[v] = 1;
d[v] = d[u] + 1;
q[tail++] = v;
if(v == t) return true;
}
}
}
return false;
}
int dfs(int u, int a) {
if(u==t || a==0) return a;
int flow = 0, f;
for(int &i=cur[u]; i; i=e[i].ne) {
int v = e[i].v;
if(d[v] == d[u]+1 && (f = dfs(v, min(a, e[i].c-e[i].f))) > 0) {
flow += f;
e[i].f += f;
e[i^1].f -= f;
a -= f;
if(a==0) break;
}
}
if(a) d[u] = -1;
return flow;
}
void build(int p) {
cnt = 1;
memset(h, 0, sizeof(h));
s=0; t=n+1;
for(int i=1; i<=m; i++) ins(b[i].fir, b[i].sec, inf);
for(int i=1; i<=n; i++) if(li[i].count(p)) {
if(i & 1) ins(s, i, li[i][p]);
else ins(i, t, li[i][p]);
}
}
int solve(int p) { //printf("\nsolve %d\n", p);
build(p);
int flow = 0;
while(bfs()) {
for(int i=s; i<=t; i++) cur[i] = h[i];
flow += dfs(s, inf);
}
return flow;
}
}
int main() {
//freopen("in", "r", stdin);
ios::sync_with_stdio(false); cin.tie(); cout.tie();
cin >> n >> m;
for(int i=1; i<=n; i++) cin >> a[i];
for(int i=1; i<=m; i++) {
cin >> b[i].fir >> b[i].sec;
if(b[i].sec & 1) swap(b[i].fir, b[i].sec);
}
for(int i=1; i<=n; i++) fac(i);
int ans = 0;
for(set<int>::iterator it = s.begin(); it != s.end(); it++) ans += mf::solve(*it);
cout << ans;
}
CF498C. Array and Operations [二分图]的更多相关文章
- cf498C Array and Operations
C. Array and Operations time limit per test 1 second memory limit per test 256 megabytes input stand ...
- Codeforces Round #284 (Div. 1) C. Array and Operations 二分图最大匹配
题目链接: http://codeforces.com/problemset/problem/498/C C. Array and Operations time limit per test1 se ...
- Codeforces Round #284 (Div. 1) C. Array and Operations 二分图匹配
因为只有奇偶之间有操作, 可以看出是二分图, 然后拆质因子, 二分图最大匹配求答案就好啦. #include<bits/stdc++.h> #define LL long long #de ...
- Array and Operations
A. Array and Operations Time Limit: 1000ms Memory Limit: 262144KB 64-bit integer IO format: %I64d ...
- 网络流(最大流):CodeForces 499E Array and Operations
You have written on a piece of paper an array of n positive integers a[1], a[2], ..., a[n] and m goo ...
- Codeforces 498C Array and Operations(最大流)
题目是给一些数和<数对>的下标,然后进行操作:对某个<数对>中的两个数同时除以一个都能被它们整除且不等于1的数,要求的就是最多能进行多少次操作. 除数一定是素数,就是要决定某素 ...
- codeforcese 498C. Array and Operations 网络流
题目链接 给n个数, m个数对, 每个数对是两个下标加起来为奇数的两个数.每次操作可以使一个数对中的两个数同时除某个数, 除的这个数是这两个数的任意约数, 问这种操作最多可以做几次.n<100, ...
- ZOJ 3427 Array Slicing (scanf使用)
题意 Watashi发明了一种蛋疼(eggache) 语言 你要为这个语言实现一个 array slicing 函数 这个函数的功能是 有一个数组初始为空 每次给你一个区间[ l, r) 和 ...
- Codeforces Round #284 (Div. 1)
A. Crazy Town 这一题只需要考虑是否经过所给的线,如果起点和终点都在其中一条线的一侧,那么很明显从起点走点终点是不需要穿过这条线的,否则则一定要经过这条线,并且步数+1.用叉积判断即可. ...
随机推荐
- C++ 常见面试题目
const作用 (1)可以定义const常量,具有不可变性. (2)便于进行类型检查.(而宏不会进行类型检查). (3)可以保护被修饰的东西,防止意外的修改. (4) 可以节省空间. static作用 ...
- 【Android入门】一个App学会安卓开发
一.程序项目架构
- Corn Fields POJ - 3254 (状压dp)
题目链接: Corn Fields POJ - 3254 题目大意:给你一个n*m的矩阵,矩阵的元素只包括0和1,0代表当前的位置不能放置人,1代表当前的位置可以放人,当你决定放人的时候,这个人的四 ...
- JS 循环定时的一些思考
网上也有例子, function doSetTimeout(i) { setTimeout(function() { console.log(i); }, 1000); } for (var i = ...
- android 应用程序记录AAR
@note:接着读赵波的<android NFC开发实例详解>,单独列出这篇文章一是因为上一篇笔记太长了,网页编辑器不太方便编写,二是这部分的知识是android开发中的知识,以后也许会深 ...
- apache无法启动报错No space left on device
apache无法启动报错No space left on device 故障现象:apache无法启动ipcs信号量很多 # service httpd startStarting httpd : [ ...
- linux查找删除某天前的文件(转载)
语句写法:find 对应目录 -mtime +天数 -name "文件名" -exec rm -rf {} \; 例1: 将/usr/local/backups目录下所有10天前带 ...
- js-图片预加载
//图片预加载 //闭包模拟局部作用于 (function($){ function Preload(imgs,options){ this.imgs = (typeof imgs === 'st ...
- Linux基础 -Ubuntu
Ubuntu 下: sudo 以管理员权限执行 apt 是Advanced Packaging Tool ,Ubuntu下的安装包管理工具,早期使用apt-get,从Ubuntu16开始建议使用apt ...
- [原创]Xilinx Vivado 2017.4/2018.3/2016.4/2015.4/ISE14.7下载及其安装
最新版本Vivado 2018.3下载地址 链接:https://pan.baidu.com/s/17aE-vICRQYN27bD2sXCLxg提取码:ilg5 由于工程需要,下载VIVADO2018 ...