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

题目链接:

http://codeforces.com/problemset/problem/498/C

C. Array and Operations

time limit per test1 second
memory limit per test256 megabytes
#### 问题描述 > You have written on a piece of paper an array of n positive integers a[1], a[2], ..., a[n] and m good pairs of integers (i1, j1), (i2, j2), ..., (im, jm). Each good pair (ik, jk) meets the following conditions: ik + jk is an odd number and 1 ≤ ik < jk ≤ n. > > In one operation you can perform a sequence of actions: > > take one of the good pairs (ik, jk) and some integer v (v > 1), which divides both numbers a[ik] and a[jk]; > divide both numbers by v, i. e. perform the assignments: and . > Determine the maximum number of operations you can sequentially perform on the given array. Note that one pair may be used several times in the described operations. #### 输入 > The first line contains two space-separated integers n, m (2 ≤ n ≤ 100, 1 ≤ m ≤ 100). > > The second line contains n space-separated integers a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ 109) — the description of the array. > > The following m lines contain the description of good pairs. The k-th line contains two space-separated integers ik, jk (1 ≤ ik < jk ≤ n, ik + jk is an odd number). > > It is guaranteed that all the good pairs are distinct. #### 输出 > Output the answer for the problem. ####样例输入 > 3 2 > 8 12 8 > 1 2 > 2 3

样例输出

2

题意

给你n个数a[],然后m个顶点对ik,jk,满足ik+jk==odd,每次操作你可以任选一个顶点对,和一个>1的整数,然后有a[ik]=a[ik]/v, a[jk]=a[jk]/v,问你最多能操作几次,v必须是公约数。

题解

首先,它给的所有顶点对都是连接下标为奇偶的,这是在暗示我们它是各二部图!一个贪心的想法,显然我们选的v肯定是质因子,而且不同的质因子是独立的。 我们可以枚举所有的质因子,对每个质因子都建一张图,跑最大流。

代码

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf

typedef int LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;

const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);

//start----------------------------------------------------------------------
const int maxn=111;

struct Edge{
    int u,v,cap,flow;
    Edge(int u,int v,int c,int f):u(u),v(v),cap(c),flow(f){}
};

struct Dinic{
    int n,m,s,t;
    vector<Edge> egs;
    vector<int> G[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];

    void init(int n){
        this->n=n;
        for(int i=0;i<n;i++) G[i].clear();
        egs.clear();
    }

    void addEdge(int u,int v,int c){
        egs.pb(Edge(u,v,c,0));
        egs.pb(Edge(v,u,0,0));
        m=egs.sz();
        G[u].pb(m-2);
        G[v].pb(m-1);
    }

    bool BFS(){
        clr(vis,0);
        queue<int> Q;
        Q.push(s);
        d[s]=0;
        vis[s]=1;
        while(!Q.empty()){
            int x=Q.front(); Q.pop();
            for(int i=0;i<G[x].sz();i++){
                Edge& e=egs[G[x][i]];
                if(!vis[e.v]&&e.cap>e.flow){
                    vis[e.v]=1;
                    d[e.v]=d[x]+1;
                    Q.push(e.v);
                }
            }
        }
        return vis[t];
    }

    int DFS(int x,int a){
        if(x==t||a==0) return a;
        int flow=0,f;
        for(int &i=cur[x];i<G[x].sz();i++){
            Edge& e=egs[G[x][i]];
            if(d[x]+1==d[e.v]&&(f=DFS(e.v,min(a,e.cap-e.flow)))>0){
                e.flow+=f;
                egs[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0) break;
            }
        }
        return flow;
    }

    int maxFlow(int s,int t){
        this->s=s;
        this->t=t;
        int flow=0;
        while(BFS()){
            clr(cur,0);
            flow+=DFS(s,INF);
        }
        return flow;
    }
}dinic;

int arr[maxn];
PII nds[maxn];

int main() {
    int n,m;
    scf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scf("%d",&arr[i]);

    VI fac;
    for(int i=1;i<=n;i++){
        int x=arr[i];
        for(int i=2;i*i<=x;i++){
            if(x%i==0){
                fac.pb(i);
                while(x%i==0) x/=i;
            }
        }
        if(x>1) fac.pb(x);
    }

    sort(all(fac));

    fac.erase(unique(all(fac)),fac.end());

    rep(i,0,m){
        int u,v;
        scf("%d%d",&u,&v);
        if(u%2) swap(u,v);
        nds[i]=mkp(u,v);
    }

    int ans=0;

    rep(i,0,fac.sz()){
        dinic.init(n+2);
        int k=fac[i];
        rep(j,0,m){
            dinic.addEdge(nds[j].X,nds[j].Y,INF);
        }
        for(int j=1;j<=n;j++){
            int c=0,x=arr[j];
            while(x%k==0) x/=k,c++;
            if(j&1){
                dinic.addEdge(j,n+1,c);
            }else{
                dinic.addEdge(0,j,c);
            }
        }
        ans+=dinic.maxFlow(0,n+1);
    }

    prf("%d
",ans);

    return 0;
}

//end-----------------------------------------------------------------------
原文地址:https://www.cnblogs.com/fenice/p/5894678.html