AC日记——[Sdoi2016]数字配对 bzoj 4514
思路:
很受伤现在,,测了那么多次不过的原因就是因为INF不够大;
解法有两种:
解法1:
把n个点按照质因数个数为奇或偶分为两个点集(很容易就可以想到);
然后,按照题目连边跑最大费用流;
当累计的能量马上就要小于0时,退出循环,输出答案;
解法2:
把n个点拆成2*n个点,也是两个集合;
如果ai[i]到ai[j]可以连边,则i连j+n,同时j连i+n;
当累计的能量马上就要小于0时,退出循环,输出答案/2;
来,上代码:
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define ll long long
- #define INF 0x7ffffffffff
- ll n,prime[],num_prime=,ai[],bi[],ci[];
- ll s,t,head[],E[],V[],W[],F[];
- ll cnt=,pre[],que[],dis[];
- bool if_prime[],d1iv[],if_[];
- inline void in(ll &now)
- {
- ll if_z=;now=;
- char Cget=getchar();
- while(Cget>''||Cget<'')
- {
- if(Cget=='-') if_z=-;
- Cget=getchar();
- }
- while(Cget>=''&&Cget<='')
- {
- now=now*+Cget-'';
- Cget=getchar();
- }
- now*=if_z;
- }
- void euler(ll limit)
- {
- for(ll i=;i<=limit;i++)
- {
- if(!if_prime[i]) prime[++num_prime]=i;
- for(ll j=;prime[j]*i<=limit&&j<=num_prime;j++)
- {
- if_prime[i*prime[j]]=true;
- if(i%prime[j]==) break;
- }
- }
- }
- inline bool cut(ll op)
- {
- ll res=,now=;
- while(op!=&&now<)
- {
- now++;
- while(!(op%prime[now])) op/=prime[now],res++;
- }
- return res&;
- }
- inline void edge_add(ll u,ll v,ll w,ll f)
- {
- E[++cnt]=head[u],head[u]=cnt,W[cnt]=w,F[cnt]=f,V[cnt]=v;
- E[++cnt]=head[v],head[v]=cnt,W[cnt]=-w,F[cnt]=,V[cnt]=u;
- }
- inline bool spfa()
- {
- for(ll i=s;i<=t;i++) dis[i]=-INF,if_[i]=false,pre[i]=-;
- ll h=,tail=;que[]=s,if_[s]=true,dis[s]=;
- while(h<tail)
- {
- ll now=que[h++];if_[now]=false;
- for(ll i=head[now];i;i=E[i])
- {
- if(F[i]>&&dis[V[i]]<dis[now]+W[i])
- {
- pre[V[i]]=i;
- dis[V[i]]=dis[now]+W[i];
- if(!if_[V[i]])
- {
- if_[V[i]]=true;
- que[tail++]=V[i];
- }
- }
- }
- }
- return dis[t]!=-INF;
- }
- int main()
- {
- in(n);euler(),t=n+;
- for(ll i=;i<=n;i++) in(ai[i]);
- for(ll i=;i<=n;i++) in(bi[i]);
- for(ll i=;i<=n;i++) in(ci[i]);
- for(ll i=;i<=n;i++)
- {
- if(cut(ai[i]))
- {
- d1iv[i]=true;
- edge_add(i,t,,bi[i]);
- }
- else edge_add(s,i,,bi[i]);
- }
- for(ll i=;i<=n;i++)
- {
- if(!d1iv[i])
- {
- for(ll j=;j<=n;j++)
- {
- if(d1iv[j])
- {
- ll a=max(ai[i],ai[j]),b=min(ai[i],ai[j]);
- if(a==b||a%b) continue;
- if(!if_prime[a/b]) edge_add(i,j,ci[i]*ci[j],INF);
- }
- }
- }
- }
- ll ans=,cii=;
- while(spfa())
- {
- ll now=t,pos=INF;
- while(pre[now]!=-)
- {
- pos=min(pos,F[pre[now]]);
- now=V[pre[now]^];
- }
- now=t;
- while(pre[now]!=-)
- {
- F[pre[now]]-=pos;
- F[pre[now]^]+=pos;
- now=V[pre[now]^];
- }
- if(cii+dis[t]*pos<)
- {
- ans+=cii/(-dis[t]);
- break;
- }
- ans+=pos,cii+=dis[t]*pos;
- }
- cout<<ans;
- return ;
- }
- #include <cmath>
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define maxn 205
- #define maxm 1000005
- #define ll long long
- #define INF 0x7ffffffffff
- ll que[maxm],E[maxm],V[maxm],F[maxm],W[maxm],cnt=,bi[maxn];
- ll n,head[maxn<<],s,t,dis[maxn<<],pre[maxn<<],ai[maxn],ci[maxn];
- bool if_[maxn<<];
- inline void in(ll &now)
- {
- ll if_z=;now=;
- char Cget=getchar();
- while(Cget>''||Cget<'')
- {
- if(Cget=='-') if_z=-;
- Cget=getchar();
- }
- while(Cget>=''&&Cget<='')
- {
- now=now*+Cget-'';
- Cget=getchar();
- }
- now*=if_z;
- }
- inline void edge_add(ll u,ll v,ll w,ll f)
- {
- E[++cnt]=head[u],V[cnt]=v,W[cnt]=w,F[cnt]=f,head[u]=cnt;
- E[++cnt]=head[v],V[cnt]=u,W[cnt]=-w,F[cnt]=,head[v]=cnt;
- }
- inline bool judge(ll op)
- {
- ll lit=sqrt(op);
- for(ll i=;i<=lit;i++) if(!(op%i)) return false;
- return true;
- }
- inline bool spfa()
- {
- for(ll i=s;i<=t;i++) dis[i]=-INF,pre[i]=-,if_[i]=false;
- ll h=,tail=;dis[s]=,que[]=s,if_[s]=true;
- while(h<tail)
- {
- ll now=que[h++];if_[now]=false;
- for(ll i=head[now];i;i=E[i])
- {
- if(F[i]>&&dis[V[i]]<dis[now]+W[i])
- {
- pre[V[i]]=i,dis[V[i]]=dis[now]+W[i];
- if(!if_[V[i]]) if_[V[i]]=true,que[tail++]=V[i];
- }
- }
- }
- return dis[t]!=-INF;
- }
- int main()
- {
- freopen("menci_pair.in","r",stdin);
- freopen("menci_pair.out","w",stdout);
- in(n),t=n<<|;
- for(ll i=;i<=n;i++) in(ai[i]);
- for(ll i=;i<=n;i++)
- {
- in(bi[i]);
- edge_add(s,i,,bi[i]);
- edge_add(i+n,t,,bi[i]);
- }
- for(ll i=;i<=n;i++) in(ci[i]);
- for(ll i=;i<=n;i++)
- {
- for(ll j=;j<=n;j++)
- {
- if(ai[i]<=ai[j]||ai[i]%ai[j]) continue;
- if(judge(ai[i]/ai[j]))
- {
- edge_add(i,j+n,ci[i]*ci[j],INF);
- edge_add(j,i+n,ci[i]*ci[j],INF);
- }
- }
- }
- ll ans=,cii=;
- while(spfa())
- {
- ll now=t,pos=INF;
- while(pre[now]!=-)
- {
- pos=min(pos,F[pre[now]]);
- now=V[pre[now]^];
- }
- now=t;
- while(pre[now]!=-)
- {
- F[pre[now]]-=pos;
- F[pre[now]^]+=pos;
- now=V[pre[now]^];
- }
- if(cii+dis[t]*pos<)
- {
- ans+=cii/abs(dis[t]);
- break;
- }
- ans+=pos,cii+=dis[t]*pos;
- }
- cout<<ans/;
- return ;
- }
AC日记——[Sdoi2016]数字配对 bzoj 4514的更多相关文章
- 图论(费用流):BZOJ 4514 [Sdoi2016]数字配对
4514: [Sdoi2016]数字配对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 820 Solved: 345[Submit][Status ...
- BZOJ 4514: [Sdoi2016]数字配对 [费用流 数论]
4514: [Sdoi2016]数字配对 题意: 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数 ...
- BZOJ 4514: [Sdoi2016]数字配对
4514: [Sdoi2016]数字配对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1606 Solved: 608[Submit][Statu ...
- 【bzoj4514】: [Sdoi2016]数字配对 图论-费用流
[bzoj4514]: [Sdoi2016]数字配对 好像正常的做法是建二分图? 我的是拆点然后 S->i cap=b[i] cost=0 i'->T cap=b[i] cost=0 然后 ...
- 【BZOJ4514】[Sdoi2016]数字配对 费用流
[BZOJ4514][Sdoi2016]数字配对 Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ...
- BZOJ.4514.[SDOI2016]数字配对(费用流SPFA 二分图)
BZOJ 洛谷 \(Solution\) 很显然的建二分图后跑最大费用流,但有个问题是一个数是只能用一次的,这样二分图两部分都有这个数. 那么就用两倍的.如果\(i\)可以向\(j'\)连边,\(j\ ...
- 【BZOJ 4514】[Sdoi2016]数字配对 费用流
利用spfa流的性质,我直接拆两半,正解分奇偶(妙),而且判断是否整除且质数我用的是暴力根号,整洁判断质数个数差一(其他非spfa流怎么做?) #include <cstdio> #inc ...
- 4514: [Sdoi2016]数字配对
Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对 ...
- 4514: [Sdoi2016]数字配对 费用流
链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4514 思路 EK直接贪心做 <0的时候加上剩余返回 二分图a->b的时候 把b- ...
随机推荐
- [Hdu3652]B-number(数位DP)
Description 题目大意:求小于n是13的倍数且含有'13'的数的个数. (1 <= n <= 1000000000) Solution 数位DP,题目需要包含13,且被13整除, ...
- Patrick and Shopping
Patrick and Shopping 今天 Patrick 等待着他的朋友 Spongebob 来他家玩.为了迎接 Spongebob,Patrick 需要去他家附近的两家商店 买一些吃的.他家 ...
- git上传自己的代码
感谢这个哥们的博客,不过里面有些错误. http://www.cnblogs.com/ruofengzhishang/p/3842587.html 下面是我自己的实践成功的: 这篇文章写得是windo ...
- loj2292 「THUSC 2016」成绩单
ref 我是傻逼,我啥也不会,这是我抄的. #include <iostream> #include <cstring> #include <cstdio> usi ...
- plsql编程
ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设计语言,该 ...
- 在windows64位上安装Python3.0
1.下载安装包 下载地址:https://www.python.org/downloads/ 如果要下载帮助文件:Download Windows help file 如果要下载基于网页的安装程序: ...
- Halcon18 Linux 下载
Halcon18 Linux下载地址:http://www.211xun.com/download_page_14.html HALCON 18 是一套机器视觉图像处理库,由一千多个算子以及底层的数据 ...
- C#中静态变量和 静态方法的作用
1.静态变量 在C#程序中,没有全局变量的概念,这意味着所有的成员变量只有该类的实例才能操作这些数据,这起到了“信息隐藏”的作用.但有些时候,这样做却不是个明智的选择. 假设我们要定义一个图书类,要求 ...
- HDU 4178 模拟
Roll-call in Woop Woop High Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- VS 2013插件
http://www.spersky.com/post/vsPlugins.html http://vswebessentials.com/download http://developer.51ct ...