[SDOI2016 Round1] 数字配对
2017-03-06 11:06
232 查看
COGS 2221. [SDOI2016 Round1] 数字配对
http://www.cogs.pro/cogs/problem/problem.php?pid=2221★★★ 输入文件:
menci_pair.in输出文件:
menci_pair.out简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 aiaj 是一个质数,那么这两个数字可以配对,并获得 ci×cj 的价值。
一个数字只能参与一次配对,可以不参与配对。
在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。
【输入格式】
第一行一个整数 n。第二行 n 个整数 a1、a2、……、an。
第三行 n 个整数 b1、b2、……、bn。
第四行 n 个整数 c1、c2、……、cn。
【输出格式】
一行一个数,最多进行多少次配对。【样例输入】
32 4 8
2 200 7
-1 -2 1
【样例输出】
4【提示】
测试点 1 ~ 3:n≤10,ai≤109,bi=1,∣ci∣≤105;测试点 4 ~ 5:n≤200,ai≤109,bi≤105,ci=0;
测试点 6 ~ 10:n≤200,ai≤109,bi≤105,∣ci∣≤105。
【来源】
SDOI2016 Round1 Day1费用流u
构图方法:(以样例为例)
1、2可以配对;2、3可以配对
#include<cstdio> #include<queue> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int a[201],b[201],c[201]; int front[210],next[160001],to[160001],tot,src,dec; int front1[210],from[160001],next1[160001],to1[160001]; bool use_in[210],use_out[210],v[210]; int n,fa[210]; long long dis[210],sum_cost,cost[160001],cap[160001]; int sum_flow; struct node1 { int point,id; }; queue<node1>q; queue<int>que; bool judge(int x) { for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false; return true; } void add(int u,int v) { to[++tot]=v;next[tot]=front[u];front[u]=tot; use_in[v]=true;use_out[u]=true; } void insert_edge(int u,int v,long long w,long long val) { to1[++tot]=v;from[tot]=u;next1[tot]=front1[u];front1[u]=tot;cap[tot]=w;cost[tot]=val; to1[++tot]=u;from[tot]=v;next1[tot]=front1[v];front1[v]=tot;cap[tot]=0;cost[tot]=-val; } bool spfa() { for(int i=1;i<=dec;i++) dis[i]=-1e15,fa[i]=0; que.push(src);v[src]=true; while(!que.empty()) { int now=que.front(); que.pop();v[now]=false; for(int i=front1[now];i;i=next1[i]) { if(dis[now]+1ll*cost[i]>dis[to1[i]]&&cap[i]>0) { dis[to1[i]]=dis[now]+1ll*cost[i]; fa[to1[i]]=i; if(!v[to1[i]]) { que.push(to1[i]); v[to1[i]]=true; } } } } if(dis[dec]!=-1e15) return true; return false; } void work() { while(spfa()) { long long tmp=1e15; for(int i=fa[dec];i;i=fa[from[i]]) tmp=min(cap[i],tmp); if(sum_cost+dis[dec]*1ll*tmp>=0) { sum_cost+=dis[dec]*tmp;sum_flow+=tmp; for(int i=fa[dec];i;i=fa[from[i]]) { cap[i]-=tmp;cap[i^1]+=tmp; } } else { sum_flow+=int(sum_cost/abs(dis[dec])); break; } } printf("%d",sum_flow); return ; } int main() { freopen("menci_pair.in","r",stdin); freopen("menci_pair.out","w",stdout); scanf("%d",&n); dec=n+1; for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1;i<=n;i++) scanf("%d",&c[i]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(a[i]<=a[j]) continue; if(!a[j]) continue; if(a[i]%a[j]==0&&judge(a[i]/a[j])) { add(j,i); } } tot=1; for(int i=1;i<=n;i++) if(!use_in[i]) { insert_edge(src,i,b[i],0); q.push((node1){i,1}); } while(!q.empty()) { node1 now=q.front();q.pop(); for(int i=front[now.point];i;i=next[i]) { int t=to[i]; if(now.id%2) { insert_edge(now.point,t,1e15,1ll*c[now.point]*c[t]); insert_edge(t,dec,b[t],0); q.push((node1){t,now.id+1}); } else { insert_edge(t,now.point,1e15,1ll*c[now.point]*c[t]); insert_edge(src,t,b[t],0); q.push((node1){t,now.id+1}); } } } work(); }
错误代码
相关文章推荐
- [SDOI2016 Round1] 数字配对
- bzoj4514【SDOI2016】数字配对
- Cogs 2221. [SDOI2016 Round1] 数字配对(二分图)
- cogs 2221. [SDOI2016 Round1] 数字配对
- 【LOJ】#2031. 「SDOI2016」数字配对
- [SDOI2016][bzoj4514] 数字配对 [费用流]
- Cogs 2221. [SDOI2016 Round1] 数字配对
- [Sdoi2016]数字配对
- 中兴月容纳杯 数字配对
- Educational Codeforces Round 14 C. Exponential notation 数字转科学计数法
- 4514: [Sdoi2016]数字配对
- 【bzoj4514】 Sdoi2016—数字配对
- Bzoj4514:[Sdoi2016]数字配对:网络流,费用流
- 4514: [Sdoi2016]数字配对|费用流
- 洛谷 P4068 数字配对
- bzoj 4514: 数字配对
- freemarker中的round、floor和ceiling数字的舍入处理
- [BZOJ4514] [SDOI2016] 数字配对 - 费用流
- 2014 GCJ Round 1B New Lottery Game(数位dp,x小于等于A,y小于等于B,并且x&y值小于等于K的数字个数)
- bzoj4514 [Sdoi2016]数字配对