P4068 [SDOI2016]数字配对
作者:互联网
【题意】
【分析】
我们发现直接n^2次判断就已经超时
所以我们需要考虑优化
如果a是b的倍数,且a的质因数分解的次方和比b多1,那么就可以建边
显然这里就可以建立二分图了
建好图以后,题目要求费用大于0的情况下的最大流
那么我们就贪心的增广,如果当前增广路的费用大于0,那就随便增
如果小于0,就增到费用不够为止
【代码】
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define mp make_pair #define fi firstP #define se second const int maxn=200+5; const int maxm=8e3+5; int n,m,head[maxn]; struct edge { int to,nxt; ll v,c; }e[maxm<<1]; int tot=1,S,T; void add(int x,int y,ll z,ll c) { e[++tot].to=y; e[tot].nxt=head[x]; e[tot].v=z; e[tot].c=c; head[x]=tot; e[++tot].to=x; e[tot].nxt=head[y]; e[tot].v=0; e[tot].c=-c; head[y]=tot; } const ll inf=1e18; ll dis[maxn]; int vis[maxn],pre[maxn]; bool spfa() { for(int i=S;i<=T;i++) vis[i]=0,dis[i]=-inf; dis[S]=0; queue <int> q; q.push(S); vis[S]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i;i=e[i].nxt) { int to=e[i].to; if(dis[to]<dis[u]+e[i].c && e[i].v>0) { dis[to]=dis[u]+e[i].c; pre[to]=i; if(!vis[to]) { q.push(to); vis[to]=1; } } } vis[u]=0; } return (dis[T]!=-inf); } ll mcmf() { ll cost=0,sumflow=0; while(spfa()) { ll flow=inf,co=0; for(int i=T;i!=S;i=e[pre[i]^1].to) flow=min(flow,e[pre[i]].v),co+=e[pre[i]].c; if(cost+co<0) return sumflow; if(co<0) flow=min(flow,cost/(-co)); for(int i=T;i!=S;i=e[pre[i]^1].to) { e[pre[i]].v-=flow; e[pre[i]^1].v+=flow; cost+=e[pre[i]].c*flow; } sumflow+=flow; } return sumflow; } int a[maxn],cnt[maxn],b[maxn],c[maxn]; int calc(int x) { int tot=0,lim=sqrt(x); for(int i=2;i<=lim;i++) while(x%i==0) x/=i,tot++; if(x>1) tot++; return tot; } int main() { // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); scanf("%d",&n); S=0; T=n+1; for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1;i<=n;i++) scanf("%d",&c[i]); for(int i=1;i<=n;i++) cnt[i]=calc(a[i]); for(int i=1;i<=n;i++) if(cnt[i]&1) for(int j=1;j<=n;j++) if((a[i]%a[j]==0 && cnt[i]==cnt[j]+1) || (a[j]%a[i]==0 && cnt[j]==cnt[i]+1)) add(i,j,inf,1LL*c[i]*c[j]); for(int i=1;i<=n;i++) if(cnt[i]&1) add(S,i,b[i],0); else add(i,T,b[i],0); printf("%lld",mcmf()); return 0; }
标签:pre,int,ll,define,vis,SDOI2016,P4068,配对,dis 来源: https://www.cnblogs.com/andylnx/p/14858984.html