4514: [Sdoi2016]数字配对 费用流
2018-03-14 14:35
344 查看
Description
有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。
若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数,
那么这两个数字可以配对,并获得 ci×cj 的价值。
一个数字只能参与一次配对,可以不参与配对。
在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。
有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。
若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数,
那么这两个数字可以配对,并获得 ci×cj 的价值。
一个数字只能参与一次配对,可以不参与配对。
在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。
题解:
全程%WerKeyTom_FTD,这个价值总和不小于0比较难搞,看完题解后发现是可以用类似贪心的方法来搞的,就是一直跑,跑到不能跑为止,当然二分答案之后再check也是可以的,慢一点。代码:
#include<bits/stdc++.h> using namespace std; #define LL long long #define pa pair<int,int> const LL Maxn=410; const LL inf=2147483647; LL read() { LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x*f; } LL n,a[Maxn],b[Maxn],c[Maxn],f[Maxn]; bool check(LL x,LL y) { if(f[x]+1==f[y])return(a[y]%a[x]==0); if(f[y]+1==f[x])return(a[x]%a[y]==0); return false; } LL getf(LL x) { LL re=0; for(LL i=2;i*i<=x;i++) if(x%i==0) { while(x%i==0)x/=i,re++; if(x==1)break; } if(x>1)re++; return re; } LL st,ed; struct Edge{LL x,y,next;LL d,c;}e[Maxn*Maxn*2]; LL last[Maxn],len=1; void ins(LL x,LL y,LL d,LL c) { LL t=++len; e[t].x=x;e[t].y=y;e[t].d=d;e[t].c=c; e[t].next=last[x];last[x]=t; } void addedge(LL x,LL y,LL d,LL c){ins(x,y,d,c),ins(y,x,0,-c);} LL dis[Maxn];bool in[Maxn];LL pre[Maxn]; bool spfa() { queue<int>q;q.push(st); memset(in,false,sizeof(in)); memset(dis,-63,sizeof(dis));dis[st]=0; while(!q.empty()) { LL x=q.front();q.pop();in[x]=false; for(LL i=last[x];i;i=e[i].next) { LL y=e[i].y; if(e[i].d>0&&dis[x]+e[i].c>dis[y]) { pre[y]=i; dis[y]=dis[x]+e[i].c; if(!in[y])in[y]=true,q.push(y); } } } return(dis[ed]!=-4485090715960753727LL); } int main() { n=read();st=n+1,ed=n+2; for(LL i=1;i<=n;i++)a[i]=read(),f[i]=getf(a[i]); for(LL i=1;i<=n;i++)b[i]=read(); for(LL i=1;i<=n;i++)c[i]=read(); for(LL i=1;i<=n;i++) if(f[i]&1)addedge(st,i,b[i],0); else addedge(i,ed,b[i],0); for(LL i=1;i<=n;i++) if(f[i]&1) { for(LL j=1;j<=n;j++) if(!(f[j]&1)&&check(i,j)) addedge(i,j,inf,c[i]*c[j]); } LL ans=0,v=0; while(spfa()) { LL x=ed;LL mn=inf; while(x!=st) { LL t=pre[x]; mn=min(mn,e[t].d); x=e[t].x; } if(v+mn*dis[ed]>=0) { ans+=mn; v+=mn*dis[ed]; x=ed; while(x!=st) { LL t=pre[x]; e[t].d-=mn,e[t^1].d+=mn; x=e[t].x; } } else { if(v+dis[ed]<0)break; mn=(-v)/dis[ed]; ans+=mn; break; } } printf("%lld",ans); }
相关文章推荐
- 4514: [Sdoi2016]数字配对|费用流
- [BZOJ4514][Sdoi2016]数字配对(数学+费用流)
- BZOJ4514 [Sdoi2016]数字配对 【费用流】
- 费用流 【SDOI2016】 bzoj4514 数字配对
- 【BZOJ 4514】[Sdoi2016]数字配对 费用流
- [二分图 费用流] BZOJ 4514 [Sdoi2016]数字配对
- BZOJ 4514: [Sdoi2016]数字配对(费用流)
- [Bzoj4514][Sdoi2016]数字配对(费用流)
- [BZOJ4514] [SDOI2016] 数字配对 - 费用流
- bzoj 4514: [Sdoi2016]数字配对 费用流
- [BZOJ4514][Sdoi2016]数字配对(数论+费用流)
- 【bzoj4514】[Sdoi2016]数字配对 费用流
- BZOJ 4514: [Sdoi2016]数字配对 [费用流 数论]
- BZOJ.4514.[SDOI2016]数字配对(费用流SPFA 二分图)
- 【BZOJ4514】[Sdoi2016]数字配对 费用流
- bzoj 4514: [Sdoi2016]数字配对(二分图+费用最大流)
- 图论(费用流):BZOJ 4514 [Sdoi2016]数字配对
- 【BZOJ4514】【SDOI2016】数字配对 [费用流]
- BZOJ 4514|SDOI 2016|数字配对|筛法|费用流
- bzoj4514: [Sdoi2016]数字配对(费用流)