CodeForces 498C Array and Operations(最大流)
2015-08-03 23:11
417 查看
题目链接:http://codeforces.com/problemset/problem/498/C
题意:给出N个数,再给出M对关系,每次操作可以从这M对中选出一对数同除它们的约数,问最多能进行多少次操作
思路:要操作次数多,那么对于每对数每次操作必定同除它们的素因子公约数,故而先对这N个数进行合数分解,然后再以分解出的质因子奇偶建图跑最大流
题意:给出N个数,再给出M对关系,每次操作可以从这M对中选出一对数同除它们的约数,问最多能进行多少次操作
思路:要操作次数多,那么对于每对数每次操作必定同除它们的素因子公约数,故而先对这N个数进行合数分解,然后再以分解出的质因子奇偶建图跑最大流
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <utility> #include <cmath> #include <queue> #include <set> #include <map> #include <climits> #include <functional> #include <deque> #include <ctime> #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; typedef long long ll; const int MAXN = 3000; const int MAXM = 100010; const int INF = 0x3f3f3f3f; struct Edge { int to, next, cap, flow; } edge[MAXM]; int tol; int Head[MAXN]; int gap[MAXN], dep[MAXN], cur[MAXN]; void init() { tol = 0; memset(Head, -1, sizeof(Head)); } void addedge(int u, int v, int w, int rw = 0) { edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0; edge[tol].next = Head[u]; Head[u] = tol++; edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0; edge[tol].next = Head[v]; Head[v] = tol++; } int Q[MAXN]; void BFS(int start, int end) { memset(dep, -1, sizeof(dep)); memset(gap, 0, sizeof(gap)); gap[0] = 1; int front = 0, rear = 0; dep[end] = 0; Q[rear++] = end; while (front != rear) { int u = Q[front++]; for (int i = Head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (dep[v] != -1)continue; Q[rear++] = v; dep[v] = dep[u] + 1; gap[dep[v]]++; } } } int S[MAXN]; int sap(int start, int end, int N) { BFS(start, end); memcpy(cur, Head, sizeof(Head)); int top = 0; int u = start; int ans = 0; while (dep[start] < N) { if (u == end) { int Min = INF; int inser; for (int i = 0; i < top; i++) if (Min > edge[S[i]].cap - edge[S[i]].flow) { Min = edge[S[i]].cap - edge[S[i]].flow; inser = i; } for (int i = 0; i < top; i++) { edge[S[i]].flow += Min; edge[S[i] ^ 1].flow -= Min; } ans += Min; top = inser; u = edge[S[top] ^ 1].to; continue; } bool flag = false; int v; for (int i = cur[u]; i != -1; i = edge[i].next) { v = edge[i].to; if (edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u]) { flag = true; cur[u] = i; break; } } if (flag) { S[top++] = cur[u]; u = v; continue; } int Min = N; for (int i = Head[u]; i != -1; i = edge[i].next) if (edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if (!gap[dep[u]])return ans; dep[u] = Min + 1; gap[dep[u]]++; if (u != start)u = edge[S[--top] ^ 1].to; } return ans; } vector <pair<int, int> > v[MAXN]; int num[MAXN][MAXN]; void factor(int id, int x) { int tmp = x; for (int i = 2; i <= sqrt(tmp); i++) { if (tmp % i == 0) { tmp /= i; int sz = v[id].size(); if (!sz) v[id].push_back(make_pair(i, 1)); else { if (v[id][sz - 1].first == i) v[id][sz - 1].second++; else v[id].push_back(make_pair(i, 1)); } i--; } if (tmp == 1) break; } if (tmp != 1) v[id].push_back(make_pair(tmp, 1)); if (v[id].size() == 0 && x != 1) v[id].push_back(make_pair(x, 1)); } int main() { int n, m; while (~scanf("%d%d", &n, &m)) { for (int i = 0; i < n; i++) { int x; scanf("%d", &x); factor(i, x); } init(); int cnt = 1; for (int i = 0; i < n; i++) for (int j = 0; j < v[i].size(); j++) num[i][j] = cnt++; int s = 0, t = cnt; for (int i = 0; i < n; i++) { for (int j = 0; j < v[i].size(); j++) { int id = num[i][j]; if (i % 2 == 1) addedge(s, id, v[i][j].second); else addedge(id, t, v[i][j].second); } } for (int i = 0; i < m; i++) { int x, y; scanf("%d%d", &x, &y); x--, y--; if (x % 2 == 0) swap(x, y); for (int j = 0; j < v[x].size(); j++) { int idx = num[x][j]; for (int k = 0; k < v[y].size(); k++) { int idy = num[y][k]; if (v[x][j].first == v[y][k].first) addedge(idx, idy, INF); } } } cout << sap(s, t, t + 1) << endl; } return 0; }
相关文章推荐
- Linux互通SSH免密码访问
- Tomcat Session 持久化
- 关于重装系统后,Windows和Linux双系统只能进入一个的问题
- 有关tomcat的安装与配置问题
- 扩展虚拟机内系统centos6.6硬盘空间
- OpenGL着色器语言 4-4.1.3
- Jetty 和 tomcat的比较
- tomcat配置文件server.xml详解
- Linux 开关中断系列函数探究
- Unix/linux进程及线程间同步技术总结【学习总结,请勿吐槽。。。】
- 基于Calabash-andriod的UI自动化测试(1)-环境和原理
- Linux写时拷贝技术(copy-on-write)
- myeclipse+tomcat+数据库配置
- tomcat配置外部应用
- centos 6实现ssh无密码登录的简便方法
- OpenCV第一课
- Xshell下中文乱码问题
- CentOS下使用文件构建swap
- Nginx 笔记与总结(6)Location:精准匹配
- Storm入门教程 第二章 构建Topology[转]