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

Posted cjlhy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #284 (Div. 1) C. Array and Operations 二分图匹配相关的知识,希望对你有一定的参考价值。

因为只有奇偶之间有操作, 可以看出是二分图, 然后拆质因子, 二分图最大匹配求答案就好啦。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long
using namespace std;

const int N = 5000 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;

int odd[N], even[N], ocnt, ecnt;
int L[N], R[N];
int G[N][N];
int match[N];
bool vis[N];
int n, m;

int path(int u) {
    for(int v = 1; v <= ecnt; v++) {
        if(G[u][v] && !vis[v]) {
            vis[v] = true;
            if(match[v] == -1 || path(match[v])) {
                match[v] = u;
                return 1;
            }
        }
    }
    return 0;
}

int main() {
    memset(match, -1, sizeof(match));
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        int x;
        scanf("%d", &x);
        if(i & 1) {
            L[i] = ocnt + 1;
            for(int j = 2; j * j <= x; j++) {
                if(x % j) continue;
                while(x % j == 0) {
                    odd[++ocnt] = j;
                    x /= j;
                }
            }
            if(x > 1) odd[++ocnt] = x;
            R[i] = ocnt;
        } else {
            L[i] = ecnt + 1;
            for(int j = 2; j * j <= x; j++) {
                if(x % j) continue;
                while(x % j == 0) {
                    even[++ecnt] = j;
                    x /= j;
                }
            }
            if(x > 1) even[++ecnt] = x;
            R[i] = ecnt;
        }
    }
    while(m--) {
        int u, v; scanf("%d%d", &u, &v);
        if(v & 1) swap(u, v);
        for(int i = L[u]; i <= R[u]; i++)
            for(int j = L[v]; j <= R[v]; j++)
                if(odd[i] == even[j]) G[i][j] = 1;
    }
    int ans = 0;
    for(int i = 1; i <= ocnt; i++) {
        memset(vis, false, sizeof(vis));
        if(path(i)) ans++;
    }
    printf("%d
", ans);
    return 0;
}

/*
*/

 

以上是关于Codeforces Round #284 (Div. 1) C. Array and Operations 二分图匹配的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #284 (Div. 2) C题(计算几何)解题报告

Codeforces Round #284 (Div. 1) A. Crazy Town 计算几何

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces 284E(概率)

Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)