[Codeforces 808F] [二分] [最小割] Card Game
2017-05-17 08:17
246 查看
题意大概就是选一些物品,这个物品魔力值的两两之和为合数,物品等级要小于你的等级,求你最小的等级,可以选出这样的一些物品使这些物品能力值之和>=k。
首先可以二分答案,然后就变成最小割的经典模型
魔力值为奇数的向源点连边,偶数向汇点连边,魔力值之和为合数的两个物品之间连边
首先可以二分答案,然后就变成最小割的经典模型
魔力值为奇数的向源点连边,偶数向汇点连边,魔力值之和为合数的两个物品之间连边
#include <cstdio> #include <iostream> #include <algorithm> #include <string> #include <cstring> #include <queue> #define N 110 #define inf 1<<30 using namespace std; int n,k,cnt,g,S,T; int p ,c ,l ,a ,G ,dis ,cur ; int ip[200010]; struct edge{ int t,nx,f; }E[N*N*4]; queue<int> Q; inline void add(int x,int y,int w){ E[++cnt].t=y; E[cnt].nx=G[x]; E[cnt].f=w; G[x]=cnt; E[++cnt].t=x; E[cnt].nx=G[y]; E[cnt].f=0; G[y]=cnt; } inline bool bfs(){ for(int i=1;i<=n+1;i++) dis[i]=-1; dis[S]=0; while(!Q.empty()) Q.pop(); Q.push(S); while(!Q.empty()){ int x=Q.front(); Q.pop(); for(int i=G[x];i;i=E[i].nx) if(dis[E[i].t]==-1&&E[i].f){ dis[E[i].t]=dis[x]+1; if(E[i].t==T) return 1; Q.push(E[i].t); } } return 0; } int dfs(int x,int f){ if(x==T||f==0) return f; int used=0,w; for(int &i=cur[x];i;i=E[i].nx) if(E[i].f&&dis[E[i].t]==dis[x]+1){ w=dfs(E[i].t,min(f-used,E[i].f)); E[i].f-=w; E[i^1].f+=w; if((used+=w)==f) return f; } if(!used) dis[x]=-1; return used; } int main(){ freopen("1.in","r",stdin); freopen("1.out","w",stdout); for(int i=2;i<=200000;i++) if(!ip[i]) for(int j=i+i;j<=200000;j+=i) ip[j]=1; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d%d%d",&p[i],&c[i],&l[i]); int L=1,R=100,mid,ans=-1; while(L<=R){ memset(G,0,sizeof(G)); mid=L+R>>1; g=0; cnt=1; int mx=-1,mxn; for(int i=1;i<=n;i++) if(l[i]<=mid&&c[i]==1&&p[i]>mx) mx=p[i],mxn=i; for(int i=1;i<=n;i++) if(l[i]<=mid&&(c[i]>1||i==mxn)) a[++g]=i; S=0; T=g+1; for(int i=1;i<=g;i++) if(c[a[i]]&1) add(S,i,p[a[i]]); else add(i,T,p[a[i]]); for(int i=1;i<=g;i++) if(c[a[i]]&1) for(int j=1;j<=g;j++) if((~c[a[j]]&1)&&!ip[c[a[i]]+c[a[j]]]) add(i,j,inf); int v=0; for(int i=1;i<=g;i++) v+=p[a[i]]; while(bfs()){ for(int i=0;i<=g+1;i++) cur[i]=G[i]; v-=dfs(S,inf); } if(v>=k) R=(ans=mid)-1; else L=mid+1; } printf("%d\n",ans); return 0; }
相关文章推荐
- Educational Codeforces Round 21 Problem F (Codeforces 808F) - 最小割 - 二分答案
- Codeforces 822C: Hacker, pack your bags!【二分查找】【后缀最小值】
- Codeforces 808F 网络流最小割(二分图最大点权独立集) 解题报告
- CodeForces 337C Quiz(二分,快速幂,答题得分最小值)
- 【Codeforces 808F】【网络流】Card Game 题解
- POJ 3020 Antenna Placement(二分匹配最小路径覆盖)
- UVa live6492Welcome Party(二分最大匹配之最小点覆盖)
- codeforces 606D. Lazy Student(#335 逆最小生成树)
- UVa live3126Taxi Cab Scheme(二分最大匹配之最小路径覆盖)
- CodeForces - 734C Anton and Making Potions(二分+枚举)
- Codeforces 868 D. Huge Strings (二分+随机+SAM)
- codeforces 817C Really Big Numbers 二分
- Codeforces 702 B. Powers of Two(二分)
- 牛顿迭代法代替二分 pku2728高度和除以距离和最小的生成树
- codeforces 672D 二分
- hdu 1853 Cyclic Tour (二分匹配KM最小权值 或 最小费用最大流)
- CodeForces - 891C: Envy(可撤销的并查集&最小生成树)
- 【CodeForces】702C - Cellular Network(二分)
- 【codeforces 732D】【二分+贪心】