ZOJ - 3265: Strange Game (optimized bipartite graph matching)

pro: has a length N of the array a [i], required to select k [i]> 0, such that b [i] = a [i ] ^ up different numbers k [i]% M appearing. N <= 200, M <= 1e9;

sol: limited, but all seek out and then half the number of hits of a ^ x% p is clearly undesirable. However, considering the particularity of bipartite matching, for each of the A [], a maximum seek min (N, all) to meet a condition.

min (N), because the other N-1 matches up the number of N-1, so no matter how the N-1 other matching, to find the current total number of non-paired to match.

Due to the large range of M, each for A [], we obtain the number N b [], to re-sort, discrete. Then run Hungary.

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=201;
int Laxt[maxn],Next[100010],To[100010];
int link[maxn*maxn],cnt,vis[maxn*maxn];
int a[maxn*maxn],tot,T;
vector<int>G[210];
void add(int u,int v){
    Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
}
bool dfs(int u)
{
    for(int i=Laxt[u];i;i=Next[i]){
        if(vis[To[i]]==T) continue;
        vis[To[i]]=T;
        if(!link[To[i]]||dfs(link[To[i]])){
            link[To[i]]=u;
            return true;
        }
    }
    return false;
}
int main()
{
    int N,M,x;
    while(~scanf("%d%d",&N,&M)){
        rep(i,1,N) G[i].clear();
        rep(i,1,N){
           scanf("%d",&x);
           int t=x%M,c=N;
           while(c--){
               G[i].push_back(t);
               t=1LL*t*x%M;
           }
           sort(G[i].begin(),G[i].end());
           int tot=unique(G[i].begin(),G[i].end())-G[i].begin();
           G[i].resize(tot);
        }
        tot=0;
        rep(i,1,N)
          for(int j=0;j<G[i].size();j++) a[++tot]=G[i][j];
        sort(a+1,a+tot+1);
        tot=unique(a+1,a+tot+1)-(a+1);
        rep(i,1,N) Laxt[i]=0; cnt=0;
        rep(i,1,tot) link[i]=0;
        rep(i,1,N) {
            for(int j=0;j<G[i].size();j++){
                int t=G[i][j];
                int pos=lower_bound(a+1,a+tot+1,t)-a;
                add(i,pos);
            }
        }
        int ans=0;
        rep(i,1,N){
            T++;
            if(dfs(i)) ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/hua-dong/p/11002086.html