看到这题真是一头雾水
且不说要求费用>0的时候流最大
光是匹配就解决不了啊!!
等等…哪里不对?
扫描二维码关注公众号,回复:
11606837 查看本文章
最大费用小于0怎么办啊!!!
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+10;
const int inf=1e18;
struct edge{
int to,nxt,flow,w;
}d[maxn]; int head[maxn],cnt=1,v[maxn];
void add(int u,int v,int w,int flow)
{
d[++cnt]=(edge){v,head[u],flow,w},head[u]=cnt;
d[++cnt]=(edge){u,head[v],0,-w},head[v]=cnt;
}
int n,m,s,t,dis[maxn],vis[maxn],a[maxn],b[maxn],c[maxn],flow[maxn],pre[maxn];
bool spfa()
{
for(int i=0;i<=t;i++) dis[i]=-inf;
queue<int>q; q.push(s);
flow[s]=inf;dis[s]=0;
while( !q.empty() )
{
int u=q.front(); q.pop();
vis[u]=0;
for(int i=head[u];i;i=d[i].nxt )
{
int v=d[i].to;
if( d[i].flow&&dis[v]<dis[u]+d[i].w )
{
dis[v]=dis[u]+d[i].w;
flow[v]=min( flow[u],d[i].flow );
pre[v]=i;
if( !vis[v] ) vis[v]=1,q.push(v);
}
}
}
return dis[t]!=-inf;
}
int fenjie(int x)
{
int sqr=sqrt(x),tot=0;
for(int i=2;i<=sqr;i++) while( x%i==0 ) x/=i,tot++;
if( x>1 ) tot++;
return tot;
}
signed main()
{
cin >> n;
s=0,t=n+1;
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=1;i<=n;i++) cin >> b[i];
for(int i=1;i<=n;i++) cin >> c[i];
for(int i=1;i<=n;i++) v[i]=fenjie(a[i]);
for(int i=1;i<=n;i++)
{
if( v[i]&1 ) add(s,i,0,b[i]);
else add(i,t,0,b[i]);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if( i==j ) continue;
if( a[i]%a[j]==0&&v[i]==v[j]+1 )
{
if( v[i]&1 ) add(i,j,c[i]*c[j],inf);
else add(j,i,c[i]*c[j],inf);
}
}
int maxcost=0,maxflow=0;
while( spfa() )
{
if( maxcost+flow[t]*dis[t]>=0 ) maxcost+=flow[t]*dis[t];
else
{
maxflow-=(maxcost/dis[t]);
break;
}
maxflow+=flow[t];
int x=t,i;
while( x!=s )
{
i=pre[x];
d[i].flow-=flow[t],d[i^1].flow+=flow[t];
x=d[i^1].to;
}
}
cout << maxflow;
}