【BZOJ-3308】九月的咖啡店 最大费用最大流 + 线性筛素数
3308: 九月的咖啡店
Time Limit: 30 Sec Memory Limit: 128 MB
Submit:
159 Solved: 56
[Submit][Status][Discuss]
Description
深绘里在九份开了一家咖啡让,如何调配咖啡民了她每天的头等大事我们假设她有N种原料,第i种原料编号为i,调配一杯咖啡则需要在这里若干种兑在一起。不过有些原料不能同时在一杯中,如果两个编号为i,j的原料,当且仅当i与j互质时,才能兑在同一杯中。现在想知道,如果用这N种原料来调同一杯咖啡,使用的原料编号之和最大可为多少。
Input
一个数字N
Output
如题
Sample Input
Sample Output
HINT
1<=N<=200000
Source
Solution
从N的范围,难以直接看出是网络流,但仔细分析,还是可以想到的
比较厉害的建图,首先需要两个结论:
1.一个数的质因子,最多有两个
2.并且这两个质因子,一个小于$\sqrt{n}$,一个大于$\sqrt{n}$
那么可以考虑筛出1~n的素数
考虑建二分图
源向小于$\sqrt{n}$的质数连边,容量为1,费用为0
大于$\sqrt{n}$的质数向汇连边,容量为1,费用为0
小于$\sqrt{n}$的质数$a$向大于$\sqrt{n}$的质数$b$连边,容量为1,费用为$V_{ab}-V_{a}-V_{b}$
$V_{a}$表示单独选$a$的最大收益$V_{a}=a^{lgn/lga}$
$V_{b}$表示单独选$b$的最大收益$V_{b}=b$
$V_{ab}$表示同时选$a$和$b$的最大收益$V_{ab}=a^{lg(n/b)/lga}*b$
这样效率并不是特别的高,那么还可以加上两个优化:
1.如果一个质数>n/2,那么它只能单独选,不用连边
2.如果一条边的费用<0,那么完全可以不连
然后考虑 最大费用最大流 即可
Code
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
inline int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; char ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxn 200010
#define maxm 200000*10+10
#define inf 0x7fffffff
int n,ans;
struct Edgenode{int next,to,from,cap,cost;}edge[maxm];
int head[maxn],cnt=;
//init
inline void add(int u,int v,int w,int c)
{
cnt++; edge[cnt].next=head[u]; head[u]=cnt;
edge[cnt].from=u; edge[cnt].to=v; edge[cnt].cap=w; edge[cnt].cost=c;
}
inline void insert(int u,int v,int w,int c)
{add(u,v,w,c); add(v,u,,-c);}
//addedge
bool mark[maxn];int dis[maxn],S,T;
inline bool spfa()
{
queue<int>q; memset(mark,,sizeof(mark));
for (int i=S; i<=T; i++) dis[i]=-inf;
q.push(S); mark[S]=; dis[S]=;
while (!q.empty())
{
int now=q.front(); q.pop();
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]<dis[now]+edge[i].cost)
{
dis[edge[i].to]=dis[now]+edge[i].cost;
if (!mark[edge[i].to])
mark[edge[i].to]=,q.push(edge[i].to);
}
mark[now]=;
}
return dis[T]>;
}
inline int dfs(int loc,int low)
{
mark[loc]=;
if (loc==T) return low;
int w,used=;
for (int i=head[loc]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==dis[loc]+edge[i].cost && !mark[edge[i].to])
{
w=dfs(edge[i].to,min(low-used,edge[i].cap));
edge[i].cap-=w; edge[i^].cap+=w; used+=w;
ans+=w*edge[i].cost; if (used==low) return low;
}
return used;
}
inline void zkw()
{
int tmp=;
while (spfa())
{
mark[T]=;
while (mark[T])
memset(mark,,sizeof(mark)),tmp+=dfs(S,inf);
}
}
//MaxflowMaxcost
bool flag[maxn]; int prime[maxn],tot;
inline void prework(int maxx)
{
flag[]=;
for (int i=; i<=maxx; i++)
{
if (!flag[i]) prime[++tot]=i;
for (int j=; j<=tot && i*prime[j]<=maxx; j++)
{
flag[i*prime[j]]=;
if (!(i%prime[j])) break;
}
}
}
//get prime
inline int calc(int n,int x)
{
long long t=x;
while (t*x<=n) t=t*x;
return t;
}
//calc
inline void make()
{
S=,T=tot+; int pos=;
for (int i=; i<=tot; i++)
{
if (prime[i]>=n/) {ans+=prime[i];continue;}
if ((long long)prime[i]*prime[i]<=n)
insert(S,i,,),ans+=calc(n,prime[i]);
else
pos=(!pos)?i:pos,insert(i,T,,),ans+=prime[i];
}
for (int i=; i<pos; i++)
for (int j=pos; j<=tot; j++)
{
if ((long long)prime[i]*prime[j]>n) break;
int tmp=calc(n/prime[j],prime[i])*prime[j]-calc(n,prime[i])-prime[j];
if (tmp>) insert(i,j,,tmp);
}
}
//build
int main()
{
n=read();
prework(n);
make();
zkw();
printf("%d\n",ans+);
return ;
}
忽略桑心病狂的inline.. && 自己YY的最大费用最大流...好像还可以?
【BZOJ-3308】九月的咖啡店 最大费用最大流 + 线性筛素数的更多相关文章
- 【BZOJ 3308】 3308: 九月的咖啡店 (费用流|二分图最大权匹配)
3308: 九月的咖啡店 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 244 Solved: 86 Description 深绘里在九份开了一家咖 ...
- bzoj 3308: 九月的咖啡店【最大费用最大流】
费用流里spfa最后的判断要写成dis[t]>=0而不是dis[t]!=-inf否则会WAWAWA-- #include<iostream> #include<cstdio&g ...
- bzoj 3308 九月的咖啡店
题目大意: 求若干个<=n的数 两两互质 使和最大 求这个最大的和 思路: 显然,得到两个结论 1 最终的所有数都只能分解为两个质因数 2 这两个质因数 一个<根号n 一个>根号n ...
- BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流
传送门 BZOJ 2668 题解 同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x).中间点mi(x).出点ou(x). 如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, ...
- BZOJ 1061 志愿者招募(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布 ...
- bzoj 1070 [SCOI2007]修车(最小费用最大流)
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3515 Solved: 1411[Submit][Status] ...
- BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)
不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...
- bzoj 3171: [Tjoi2013]循环格 最小费用最大流
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3171 题解: 首先我们很容易发现一个结论: 出现完美循环当且仅当所有点的出入度均为1 所 ...
- bzoj 1070: [SCOI2007]修车【最小费用最大流】
一开始从客人角度想的,怎么建都不对 从一个修车工所接待的所有顾客花费的总时间来看,设一共有x个人,那么第一个修的对总时间的贡献是x*w1,第二个是(x-1)*w2-以此类推.所以把第i个修车工拆成n组 ...
随机推荐
- memcached的图形界面监控
前提是已经安装了php和memcached 图形界面的监控是通过memcache.php来实现的, 1.把该php程序拷贝到apache的web根目录 [root@cacti srv]# ...
- 使用ViewBag传送数据从控制器至视图
前一篇<ASP.NET MVC读取XML并使用ViewData显示>http://www.cnblogs.com/insus/p/4308740.html 中,在控制器中使用了ViewDa ...
- codevs2806 红与黑
难度等级:白银 codevs2806 红与黑 题目描述 Description 有一个矩形房间,覆盖正方形瓷砖.每块瓷砖涂成了红色或黑色.一名男子站在黑色的瓷砖上,由此出发,可以移到四个相邻瓷砖之一, ...
- weblogic启动失败:Could not obtain the localhost address 解决办法
linux下weblogic启动如果出现这个错误,多半是hosts文件不对 1.先输入hostname,查看本机计算机名(比如:server123) 2.sudo vi /etc/hosts 编辑ho ...
- FineUI v4.0.3 (beta) 和 FineUI v3.3.3 发布了!
关于FineUI基于 ExtJS 的开源 ASP.NET 控件库 FineUI的使命创建 No JavaScript,No CSS,No UpdatePanel,No ViewState,No Web ...
- 虚拟机开机提示Operating System not found解决办法
为了更好体验windows更多操作系统,有些用户会在VMware虚拟机中安装XP.win7或win8等等系统,有用户反映在虚拟机中安装XP开机后提示"Operating System not ...
- JavaScript UI选型及Jquery EasyUI使用经验谈
最近由于项目需要,对js UI作了一些简单的了解和使用,有自己的一些想法,在这里留个记录. 当然,我的专注点在管理系统的范围内,所以互联网网站及其他形态的应用这里不提及,所以jQuery UI和Boo ...
- C#中的interface
接口(interface) 接口泛指实体把自己提供给外界的一种抽象化物(可以为另一实体),用以由内部操作分离出外部沟通方法,使其能被修改内部而不影响外界其他实体与其交互的方式. 接口实际上是一个约定: ...
- 1031MVCC和事务浅析
转自 http://blog.csdn.net/sofia1217/article/details/50778906 关于MVCC浅析,有些难度http://xuebinbin212.blog.163 ...
- 写启动界面Splash的正确姿势,解决启动白屏(转)
原文链接:http://www.jianshu.com/p/cd6ef8d3d74d 从我学习写第一个android项目以来,我都是这样写着启动界面: 在里面做一些事,比如:第一次启动时拷贝数据. 然 ...