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) 和 ...
随机推荐
- mongodb cpu 超过100%居高不下的原因分析过程
-- mongodb cpu is high, infomation as below: 1 the message in the http://10.100.1.11:28017/ as below ...
- 编tuxedo遇到服务问题
各种错误的程序报构建服务: 1. 配置为执行环境变量tmboot –y启动管理流程和服务流程 2. 每日班似这个错误:buildserv:error while loading shared li ...
- 游戏开场镜头拉近(Unity3D开发之四)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/? p=553 今天看了个Demo.发现 ...
- EasyUI中datagrid实现显示、增加、 删除、 修改、 查询操作(后台代码C#)
菜鸟进入,高手请绕道! +++++++++++++++++++++++++++++++++++++++ 一.数据的显示 1新建HtmlPage2.html页面,引入相关文件.如下所示 <scri ...
- WPF基础——继承
1) 可以定义继承自其他类的类,关系是“父类/子类”.子类继承父类的成员(不严谨) 2) 定义语法“class子类:父类”,不指定父类则父类为Object,.Net中所有类都直接或者间接继承自Ob ...
- cron 定时任务
cron 是linux下的定时任务: M H D m d cmd. 这是一种cron文件格式. M: 分钟(0-59). H:小时(0-23). D:天(1-31). m: 月(1-12). d ...
- HTML系列(九):表单
一.表单标签form 表单标签用于申明表单,定义采集数据的范围,即<form>包含的数据将被提交到数据库上,包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单能够包 ...
- Hadoop插件安装
1.首先下载Hadoop对应版本的插件,以Hadoop 1.0版本对应的插件Hadoop-eclipse-plugin1.0.3.jar为例 2.将下载的插件放置到Ecplise安装目录的plugin ...
- ffmpeg用法
1. help ffmpeg.exe -h > help.txt 2. 解码: ffmpeg -i 123.264 123.yuv ffmpeg -i 123.264 -vframes 200 ...
- MYSQL 执行计划
Explain语法 EXPLAIN SELECT …… 变体: 1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得 ...