不会有奇环,那么就建二分图
然后跑最大费用流,直到费用小于零为止,处理下零头
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
#define oo 1LL<<60
#define V G[p].v
using namespace std;
typedef long long ll;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=205;
struct edge{
int u,v,f; ll w;
int next;
};
edge G[N*N*10];
int head[N],inum=1;
inline void add(int u,int v,ll w,int f,int p){
G[p].u=u; G[p].v=v; G[p].w=w; G[p].f=f; G[p].next=head[u]; head[u]=p;
}
inline void link(int u,int v,ll w,int f){
add(u,v,w,f,++inum); add(v,u,-w,0,++inum);
}
int S,T;
const int ND=1000000;
int Q[ND],l,r;
int ins[N],pre[N];
ll dis[N];
ll Mincost,last,Flow;
inline bool SPFA()
{
l=r=-1; cl(ins); cl(Q); cl(pre); for (int i=1;i<=T;i++) dis[i]=-oo;
Q[(++r)%ND]=S; ins[S]=1; dis[S]=0;
while (l!=r)
{
int u=Q[(++l)%ND]; ins[u]=0;
for (int p=head[u];p;p=G[p].next)
if (G[p].f && dis[V]<dis[u]+G[p].w)
{
dis[V]=dis[u]+G[p].w; pre[V]=p;
if (!ins[V])
Q[(++r)%ND]=V,ins[V]=1;
}
}
if (dis[T]==-oo) return 0;
ll flow=1<<30,cost=dis[T];
for (int p=pre[T];p;p=pre[G[p].u]) flow=min(flow,(ll)G[p].f);
last=Mincost;
Mincost+=flow*cost;
if (Mincost<0)
{
Flow+=last/-cost;
printf("%lld\n",Flow);
exit(0);
}
Flow+=flow;
for (int p=pre[T];p;p=pre[G[p].u])
G[p].f-=flow,G[p^1].f+=flow;
return 1;
}
int n;
int a[N],b[N],c[N];
const int maxn=100000;
int prime[maxn+5],vst[maxn+5],pnum;
inline void Pre()
{
for (int i=2;i<=maxn;i++)
if (!vst[i])
{
prime[++pnum]=i;
for (int j=i+i;j<=maxn;j+=i) vst[j]=1;
}
}
inline bool Jud(int x){
if (x==1) return 0;
for (int i=1;i<=pnum && (ll)prime[i]*prime[i]<=x;i++)
if (x%prime[i]==0)
return 0;
return 1;
}
int tag[N][N];
int clr[N];
void dfs(int u,int c){
clr[u]=c;
for (int i=1;i<=n;i++)
if (i!=u && clr[i]==-1 && tag[i][u])
dfs(i,c^1);
}
int main()
{
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
Pre();
read(n);
for (int i=1;i<=n;i++) read(a[i]);
for (int i=1;i<=n;i++) read(b[i]);
for (int i=1;i<=n;i++) read(c[i]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if ((a[i]%a[j]==0 && Jud(a[i]/a[j])) || (a[j]%a[i]==0 && Jud(a[j]/a[i])))
tag[i][j]=1;
memset(clr,-1,sizeof(clr));
for (int i=1;i<=n;i++)
if (clr[i]==-1)
dfs(i,0);
S=n+1; T=n+2;
for (int i=1;i<=n;i++)
if (!clr[i])
link(S,i,0,b[i]);
else
link(i,T,0,b[i]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (!clr[i] && clr[j] && tag[i][j])
link(i,j,(ll)c[i]*c[j],1<<30);
while (SPFA());
printf("%lld\n",Flow);
return 0;
}