codeforcese 498C. Array and Operations 网络流
给n个数, m个数对, 每个数对是两个下标加起来为奇数的两个数。每次操作可以使一个数对中的两个数同时除某个数, 除的这个数是这两个数的任意约数, 问这种操作最多可以做几次。n<100, m<100。
这个数据范围, 以及下标加起来为奇数...好明显的网络流暗示。
首先对每个数分解, 看它含有哪些素因子, 每个素因子的个数是多少, 因为只有100个数, 所以素因子的总数不是很多。
然后枚举每个素因子。对每个数对中的两个数连边, 如果下标是奇数, 源点就向这个数连边, 下标是偶数, 这个数向汇点连边。 权值为这个数含有这个素因子的个数。
然后跑很多遍网络流, 答案就是所有结果相加。
具体可以看代码
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
map <int, int> mp[], ma;
pll b[];
const int maxn = 2e4;
int q[maxn*], head[maxn*], dis[maxn/], s, t, num;
int vis[];
struct node
{
int to, nextt, c;
node(){}
node(int to, int nextt, int c):to(to), nextt(nextt), c(c){}
}e[maxn*];
void init() {
num = ;
mem1(head);
mem(vis);
}
void add(int u, int v, int c) {
e[num] = node(v, head[u], c); head[u] = num++;
e[num] = node(u, head[v], ); head[v] = num++;
}
int bfs() {
mem(dis);
dis[s] = ;
int st = , ed = ;
q[ed++] = s;
while(st<ed) {
int u = q[st++];
for(int i = head[u]; ~i; i = e[i].nextt) {
int v = e[i].to;
if(!dis[v]&&e[i].c) {
dis[v] = dis[u]+;
if(v == t)
return ;
q[ed++] = v;
}
}
}
return ;
}
int dfs(int u, int limit) {
if(u == t) {
return limit;
}
int cost = ;
for(int i = head[u]; ~i; i = e[i].nextt) {
int v = e[i].to;
if(e[i].c&&dis[v] == dis[u]+) {
int tmp = dfs(v, min(limit-cost, e[i].c));
if(tmp>) {
e[i].c -= tmp;
e[i^].c += tmp;
cost += tmp;
if(cost == limit)
break;
} else {
dis[v] = -;
}
}
}
return cost;
}
int dinic() {
int ans = ;
while(bfs()) {
ans += dfs(s, inf);
}
return ans;
}
int main()
{
int n, m, x;
cin>>n>>m;
for(int i = ; i<n; i++) {
scanf("%d", &x);
for(int j = ; j*j<=x; j++) {
if(x%j==) {
mp[i][j] = ; //mp是看第i个数含有素数j的个数
ma[j] = ; //ma是存储这n个数所有的素因子
}
while(x%j==) {
x/=j;
mp[i][j]++;
}
}
if(x>) {
mp[i][x] = ;
ma[x] = ;
}
}
for(int i = ; i<m; i++) {
cin>>b[i].fi>>b[i].se;
b[i].fi--, b[i].se--;
}
auto it = ma.begin();
int ans = ;
while(it != ma.end()) {
int pri = it->first; //枚举所有素因子
init();
s = n+, t = n+;
for(int i = ; i<m; i++) {
if(b[i].fi%==) {
add(b[i].fi, b[i].se, inf);
if(!vis[b[i].fi]) {
add(s, b[i].fi, mp[b[i].fi][pri]); //如果这个数之前没出现过, 那么就向源点或者汇点连边。
vis[b[i].fi] = ;
}
if(!vis[b[i].se]) {
add(b[i].se, t, mp[b[i].se][pri]);
vis[b[i].se] = ;
}
} else {
add(b[i].se, b[i].fi, inf);
if(!vis[b[i].fi]) {
add(b[i].fi, t, mp[b[i].fi][pri]);
vis[b[i].fi] = ;
}
if(!vis[b[i].se]) {
add(s, b[i].se, mp[b[i].se][pri]);
vis[b[i].se] = ;
}
}
}
int tmp = dinic();
ans += tmp;
it++;
}
cout<<ans<<endl; }
codeforcese 498C. Array and Operations 网络流的更多相关文章
- Codeforces 498C Array and Operations(最大流)
题目是给一些数和<数对>的下标,然后进行操作:对某个<数对>中的两个数同时除以一个都能被它们整除且不等于1的数,要求的就是最多能进行多少次操作. 除数一定是素数,就是要决定某素 ...
- cf498C Array and Operations
C. Array and Operations time limit per test 1 second memory limit per test 256 megabytes input stand ...
- CF498C. Array and Operations [二分图]
CF498C. Array and Operations 题意: 给定一个长为 n 的数组,以及 m 对下标 (a, b) 且满足 a + b 为奇数,每次操作可以将同一组的两个数同时除以一个公约数 ...
- 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 ...
- 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 Round #284 (Div. 1) C. Array and Operations 二分图匹配
因为只有奇偶之间有操作, 可以看出是二分图, 然后拆质因子, 二分图最大匹配求答案就好啦. #include<bits/stdc++.h> #define LL long long #de ...
- Codeforces 最大流 费用流
这套题目做完后,一定要反复的看! 代码经常出现的几个问题: 本机测试超时: 1.init函数忘记写. 2.addedge函数写成add函数. 3.边连错了. 代码TLE: 1.前向星边数组开小. 2. ...
- ZOJ 3427 Array Slicing (scanf使用)
题意 Watashi发明了一种蛋疼(eggache) 语言 你要为这个语言实现一个 array slicing 函数 这个函数的功能是 有一个数组初始为空 每次给你一个区间[ l, r) 和 ...
随机推荐
- findOneAndUpdate的用法详解
Fragment.findOneAndUpdate({_id:id}, {$set: datas}, {upsert:true, 'new':true}).populate('ads').exec(f ...
- Filter及FilterChain的使用具体解释
一.Filter的介绍及使用 什么是过滤器? 与Servlet类似,过滤器是一些web应用程序组件,能够绑定到一个web应用程序中.可是与其它web应用程序组件不同的是,过滤器是"链&quo ...
- iWeb峰会见闻
8.16去参加了iWeb峰会,一大早8点过10分就到了,发现外面已经排起了长队(说明影响力越来越大,关注的人越来越多了.) 此次大会参与的企业也越来越多,当然是有目的而来~ 上午 google商业合作 ...
- JS实现快排
/*采用快排的方法排序,取第一个值为轴对数组进行分割排序,不断迭代后实现数组的排序*/ //定义分割函数 function partF(A,low, high){ var temp = A[low]; ...
- 解决Eclipse无法打开“Failed to load the JNI shared library”(转)
一般说来,新购笔记本会预装64位的windows系统,而在网上下载软件时,32位会优先出现在页面中(现在来说是这个情况,但我认为未来64位会越来越普及).如果你是64位的系统,却安装了32位的JDK, ...
- This project references NuGet package(s) that are missing on this computer.
Install Nuget. Right click on the solution and select "Enable NuGet Package Restore". Clic ...
- 七种Prolog解释器/编译器
http://blog.sina.com.cn/s/blog_494e45fe0100lh1v.html PROLOG 人工智能领域常用的语言,开发自然语言分析,专家系统,以及所有和智能有关的程序,都 ...
- [翻译]如何用YII写出安全的WEB应用
前言 虽然本文是基于YII1.1,但其中提到的安全措施适用于多数web项目安全场景,所以翻译此文,跟大家交流.原文地址. 目录 安全基本措施... 2 验证与过滤用户的输入信息... 2 原理... ...
- SQL Server 数据库备份到域中别的机器上
backup database dbName to disk = '\\SV2\D\dbbackup\dbName.bak' with init,compression;
- 【Perl学习笔记】1.perl的ref 函数
perl有引用的概念:一组数据实际上是另一组数据的引用.这些引用称为指针,第一组数据中存放的是第二组数据的头地址.引用的方式被用得相当普遍,特别是在面向对象的模块.函数的参数传递等常见.但perl对每 ...