[BZOJ4514] [SDOI2016] 数字配对 - 费用流
来源:互联网 发布:淘宝吊坠 编辑:程序博客网 时间:2024/05/29 19:43
显然可以根据质因子个数建二分图,再连源点和汇点,连边就可以跑费用流了。每次跑最大费用,直到费用小于0就结束过程,记录总流量即可 - -
#include"bits/stdc++.h"using namespace std;typedef long long ll; const int N=40005,M=50000;const int inf=(int)1e9;const ll llinf=(ll)1e18; int pri[M+5 >> 2],cnt,flag[M+5];void Linear_Shaker(){ for(int i=2;i<=M;i++){ if(!flag[i])pri[++cnt]=i; for(int j=1;pri[j]*i<=M;j++){ flag[pri[j]*i]=1; if(i%pri[j]==0)break; } }} int a[N],n,f[N],c[N],color[N],S,T;struct Edge { int to;ll cost,flow; Edge (int _=0,ll __=0,ll ___=0) { to=_; flow=__; cost=___;}} e[N << 1];int head[N],next[N << 1],tmp=1; inline void addedge(int fr,int to,ll cost,int flow){ e[++tmp]=Edge(to,flow,cost);next[tmp]=head[fr];head[fr]=tmp; e[++tmp]=Edge(fr,0,-cost);next[tmp]=head[to];head[to]=tmp;} int sep(int x){ int ans=0;if(x<2)return 0; for(int i=1;pri[i]*pri[i]<=x;i++) while(x%pri[i]==0)ans++,x/=pri[i]; return ans+(x>1);} void init(){ Linear_Shaker(); scanf("%d",&n);int i,j,s,t;S=0,T=n+1; for(i=1;i<=n;i++)scanf("%d",&a[i]); for(i=1;i<=n;i++)scanf("%d",&f[i]); for(i=1;i<=n;i++)scanf("%d",&c[i]); for(i=1;i<=n;i++)color[i]=sep(a[i]); for(i=1;i<=n;i++)for(j=i+1;j<=n;j++){ s=i,t=j;if(a[i]<a[j])swap(s,t); if(a[s]%a[t]==0&&color[s]==color[t]+1){ s=i,t=j;if(color[i]&1)swap(s,t); addedge(s,t,(ll)c[i]*c[j],inf); } } for(i=1;i<=n;i++) if(color[i]&1)addedge(i,T,0,f[i]); else addedge(S,i,0,f[i]);} int pre[N],q[N],l,r,inq[N],id[N];ll dist[N]; bool spfa(){ for(int i=S;i<=T;i++)dist[i]=-llinf,pre[i]=id[i]=0; dist[S]=0;l=r=1;q[++r]=S;inq[S]=1; while(l!=r){ l=(l+1)%(n+3); int s=q[l];inq[s]=0; for(int i=head[s];i;i=next[i]){ if(e[i].flow>0){ if(dist[s]+e[i].cost>dist[e[i].to]){ dist[e[i].to]=dist[s]+e[i].cost; pre[e[i].to]=s;id[e[i].to]=i; if(!inq[e[i].to]){ r=(r+1)%(n+3); q[r]=e[i].to; inq[e[i].to]=1; } } } } } return pre[T]!=0;} void work(){ ll maxflow=0,i,flow,sumcost=0; while(spfa()&&sumcost+dist[T]>=0){ flow=inf; for(i=T;i;i=pre[i]) flow=min(flow,e[id[i]].flow); if(sumcost+flow*dist[T]<0) flow=sumcost/(-dist[T]); for(i=T;i;i=pre[i]){ e[id[i]].flow-=flow; e[id[i]^1].flow+=flow; } maxflow+=flow; sumcost+=flow*dist[T]; } printf("%lld\n",maxflow);} int main(){ init();work(); return 0;}
0 0
- 【bzoj4514】[Sdoi2016]数字配对 费用流
- [BZOJ4514] [SDOI2016] 数字配对 - 费用流
- 费用流 【SDOI2016】 bzoj4514 数字配对
- Bzoj4514:[Sdoi2016]数字配对:网络流,费用流
- [bzoj4514][SDOI2016]数字配对
- BZOJ4514 [Sdoi2016]数字配对
- bzoj4514【SDOI2016】数字配对
- BZOJ4514: [Sdoi2016]数字配对
- BZOJ4514 [Sdoi2016]数字配对
- bzoj4514: [Sdoi2016]数字配对
- BZOJ4514: [Sdoi2016]数字配对
- 【BZOJ4514】数字配对,费用流
- bzoj4514 数字配对 费用流
- BZOJ4514:数字配对(费用流+数学)
- BZOJ4514——[Sdoi2016]数字配对
- 4514: [Sdoi2016]数字配对|费用流
- bzoj 4514: [Sdoi2016]数字配对 费用流
- [二分图 费用流] BZOJ 4514 [Sdoi2016]数字配对
- c# App.config配置文件读写操作
- 通过新浪云 建立自己的网站
- tolua++实现分析
- 【leetcode】12. Integer to Roman
- 算法8_最短路径—Dijkstra算法和Floyd算法
- [BZOJ4514] [SDOI2016] 数字配对 - 费用流
- C中static的常见作用
- 适配器
- 用 JavaScript 写一个超小型编译器
- hash算法
- 怎样进行ssm 的整合(spring+springmvc+mabatis)
- adb查看设备的时候,显示 List of devices attached
- iOS开发中单例设计模式、通知中心的使用
- scanf()、getch()、getchar()、getc()、gets()、gets_s()