题目链接

给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 网络流的更多相关文章

  1. Codeforces 498C Array and Operations(最大流)

    题目是给一些数和<数对>的下标,然后进行操作:对某个<数对>中的两个数同时除以一个都能被它们整除且不等于1的数,要求的就是最多能进行多少次操作. 除数一定是素数,就是要决定某素 ...

  2. cf498C Array and Operations

    C. Array and Operations time limit per test 1 second memory limit per test 256 megabytes input stand ...

  3. CF498C. Array and Operations [二分图]

    CF498C. Array and Operations 题意: 给定一个长为 n 的数组,以及 m 对下标 (a, b) 且满足 a + b 为奇数,每次操作可以将同一组的两个数同时除以一个公约数 ...

  4. 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 ...

  5. Array and Operations

    A. Array and Operations Time Limit: 1000ms Memory Limit: 262144KB 64-bit integer IO format: %I64d    ...

  6. 网络流(最大流):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 ...

  7. Codeforces Round #284 (Div. 1) C. Array and Operations 二分图匹配

    因为只有奇偶之间有操作, 可以看出是二分图, 然后拆质因子, 二分图最大匹配求答案就好啦. #include<bits/stdc++.h> #define LL long long #de ...

  8. Codeforces 最大流 费用流

    这套题目做完后,一定要反复的看! 代码经常出现的几个问题: 本机测试超时: 1.init函数忘记写. 2.addedge函数写成add函数. 3.边连错了. 代码TLE: 1.前向星边数组开小. 2. ...

  9. ZOJ 3427 Array Slicing (scanf使用)

    题意  Watashi发明了一种蛋疼(eggache) 语言  你要为这个语言实现一个 array slicing 函数  这个函数的功能是 有一个数组初始为空  每次给你一个区间[ l, r)  和 ...

随机推荐

  1. xcode KVC:Key Value Coding 键值编码

    赋值 // 能修改私有成员变量 - (void)setValue:(id)value forKey:(NSString *)key; - (void)setValue:(id)value forKey ...

  2. 自己定义flash的宽和高

    前段时间做个项目,是个网页的聊天界面,聊天的内容使用flash制作,我需要将flash的swf插件放到页面上,然后获取聊天内容, 1.将文件在页面上显现出来: 如图,正中间使用后台制作出来的swf文件 ...

  3. Css 外边距折叠(collapsed margin ) 浅析

    Css 外边距折叠(collapses margin ) a.先来看看w3c 文档对于外边距折叠的定义: In CSS, the adjoining margins of two or more bo ...

  4. 现在网页中流行的css3样式

    1.鼠标放在圆形图片中,图片渐渐的变方形[17素材头像的特效,觉得不错就研究下来了 ———— 17sucai.com] img{border-radius:50%;transition: all .4 ...

  5. VIM中格式化json

    在vim输入以下命令就可以格式化:%!python -m json.tool可以在~/.vimrc增加快捷键map <F4><Esc>:%!python -m json.too ...

  6. WCF Service Configuration Editor的使用

    原文:http://www.cnblogs.com/Ming8006/p/3772221.html 通过WCF Service Configuration Editor的配置修改Client端 参考 ...

  7. Java的函数与函数重载

    关于Java的函数与函数重载 关于Java的函数与函数重载 1. 函数 假设有一个游戏程序,程序在运行过程中,要不断地发射炮弹.发射炮弹的动作都需要使用一段百行左右的程序代码,在每次发射炮弹的地方都要 ...

  8. 一周学会Mootools 1.4中文教程:(1)Dom选择器

    利器: 君欲善其事须先利其器,好吧因为我们的时间比较紧迫,只有六天而已,那么六天的时间用死记硬背的方式学会Mt犹如天方夜谭,因此我们需要借鉴一下Editplus的素材栏帮我们记忆就好了,当我们需要用到 ...

  9. gmpy2安装使用方法

    GMP(GNU Multiple Precision Arithmetic Library,即GNU高精度算术运算库),它是一个开源的高精度运算库,其中不但有普通的整数.实数.浮点数的高精度运算,还有 ...

  10. brief introduction JAVA new I/O (NIO)

    Reference document: Getting started with new I/O (NIO) Preface: NIO was introduced with JDK1.4 for h ...