Digital collectible card games have become very popular recently. So Vova decided to try one of these.

Vova has n cards in his collection. Each of these cards is characterised by its power pi, magic number ci and level li. Vova wants to build a deck with total power not less than k, but magic numbers may not allow him to do so — Vova can't place two cards in a deck if the sum of the magic numbers written on these cards is a prime number. Also Vova cannot use a card if its level is greater than the level of Vova's character.

At the moment Vova's character's level is 1. Help Vova to determine the minimum level he needs to reach in order to build a deck with the required total power.

Input

The first line contains two integers $n$ and $k$ $(1 ≤ n ≤ 100, 1 ≤ k ≤ 100000)$.

Then n lines follow, each of these lines contains three numbers that represent the corresponding card: $p_i$, $c_i$ and $l_i$ $(1 ≤ p_i ≤ 1000, 1 ≤ c_i ≤ 100000, 1 ≤ l_i ≤ n)$.

Output

If Vova won't be able to build a deck with required power, print $ - 1$. Otherwise print the minimum level Vova has to reach in order to build a deck.

题目大意

有$n$个物品,每个物品具有属性$p_i能量,c_i魔力,l_i等级$。要求选出一些物品在满足 两两魔力和为合数 且 总能量大于等于k 的情况下等级最低。


题目分析

首先可以用二分去掉等级这一维。对物品魔力的奇偶性考虑,则可以将物品分为奇偶两列,并保证了这两列物品各自是只能组成合数的(对于特殊的素数2=1+1,需要预先只保留一个能量最大且合法的1)。

考虑以上方式的建图,直观的意义就是若选了物品i,j(各为奇偶),那么就一定会导致不合法。用边权来表示避免这种情况的代价,则是下图所示的建图方式。

由此可见,对于一种情况的最大能量,就是该图的能量总和-最小割。

听说这是一种经典的最小割模型?

 #include<bits/stdc++.h>
const int maxn = ;
const int maxm = ;
const int maxNum = ;
const int INF = 2e9; struct Edge
{
int u,v,f,c;
Edge(int a=, int b=, int c=, int d=):u(a),v(b),f(c),c(d) {}
}edges[maxm];
bool pr[maxNum];
int n,K,ans,L,R,mid,tag,cnt,S,T;
int p[maxn],c[maxn],l[maxn],sv[maxn];
int edgeTot,head[maxn],nxt[maxm],lv[maxn]; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void addedge(int u, int v, int c)
{
edges[edgeTot] = Edge(u, v, , c), nxt[edgeTot] = head[u], head[u] = edgeTot++;
edges[edgeTot] = Edge(v, u, , ), nxt[edgeTot] = head[v], head[v] = edgeTot++;
}
bool buildLevel()
{
memset(lv, , sizeof lv);
std::queue<int> q;
lv[S] = , q.push(S);
for (int tmp; q.size(); )
{
tmp = q.front(), q.pop();
for (int i=head[tmp]; i!=-; i=nxt[i])
{
int v = edges[i].v;
if (!lv[v]&&edges[i].f < edges[i].c){
lv[v] = lv[tmp]+, q.push(v);
if (v==T) return true;
}
}
}
return false;
}
int fndPath(int x, int lim)
{
if (x==T) return lim;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i].v, val;
if (lv[x]+==lv[v]&&edges[i].f < edges[i].c){
if ((val = fndPath(v, std::min(lim, edges[i].c-edges[i].f)))){
edges[i].f += val, edges[i^].f -= val;
return val;
}else lv[v] = -;
}
}
return ;
}
int dinic()
{
int ret = , val;
while (buildLevel())
while ((val = fndPath(S, INF)))
ret += val;
return ret;
}
int main()
{
n = read(), K = read();
for (int i=; i<maxNum; i++)
if (!pr[i]) for (int j=i+i; j<maxNum; j+=i)
pr[j] = true;
for (int i=; i<=n; i++)
p[i] = read(), c[i] = read(), l[i] = read();
ans = -, L = , R = , S = , T = n+;
for (mid=(L+R)>>; L<=R; mid=(L+R)>>)
{
memset(head, -, sizeof head);
sv[] = tag = cnt = edgeTot = ;
for (int i=; i<=n; i++)
if ((c[i]==&&p[i] > p[tag])&&(l[i] <= mid)) tag = i;
for (int i=; i<=n; i++)
if ((c[i]!=||i==tag)&&(l[i] <= mid)) sv[++sv[]] = i;
for (int i=; i<=sv[]; cnt += p[sv[i]], i++)
if (c[sv[i]]&) addedge(S, i, p[sv[i]]);
else addedge(i, T, p[sv[i]]);
for (int i=; i<=sv[]; i++)
if (c[sv[i]]&) for (int j=; j<=sv[]; j++)
if ((~c[sv[j]]&)&&(!pr[c[sv[i]]+c[sv[j]]]))
addedge(i, j, INF);
cnt -= dinic();
if (cnt >= K) ans = mid, R = mid-;
else L = mid+;
}
printf("%d\n",ans);
return ;
}

END

【二分 最小割】cf808F. Card Game的更多相关文章

  1. 最大密集子图(01分数规划+二分+最小割)POJ3155

    题意:给出一副连通图,求出一个子图令g=sigma(E)/sigma(V); h[g]=sigma(E)-g*sigma(V):设G是最优值 则当h[g]>0:g<G h[g]<0, ...

  2. poj 3155 二分+最小割求实型最小割(最大密集子图)

    /* 最大密集子图子图裸题 解法:设源点s和汇点t 根据胡波涛的<最小割模型在信息学中的应用> s-每个点,权值为原边权和m, 每个点-t,权值为m+2*g-degree[i], 原来的边 ...

  3. 【BZOJ2756】奇怪的游戏(二分,最小割)

    题意: Blinker最近喜欢上一个奇怪的游戏.这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻的格子,并使这两个数都加上 1.现在 Blinker 想知道最 ...

  4. hdu 1569 &1565 (二分图带权最大独立集 - 最小割应用)

    要选出一些点,这些点之间没有相邻边且要求权值之和最大,求这个权值 分析:二分图带权最大独立集. 用最大流最小割定理求解.其建图思路是:将所有格点编号,奇数视作X部,偶数视作Y部,建立源点S和汇点T, ...

  5. 【BZOJ 3232】圈地游戏 二分+SPFA判环/最小割经典模型

    最小割经典模型指的是“一堆元素进行选取,对于某个元素的取舍有代价或价值,对于某些对元素,选取后会有额外代价或价值”的经典最小割模型,建立倒三角进行最小割.这个二分是显然的,一开始我也是想到了最小割的那 ...

  6. zoj 2676 二分+ISAP模板求实型参数的最小割(0-1分数规划问题)(可做ISAP模板)

    /* 参考博文:http://www.cnblogs.com/ylfdrib/archive/2010/09/01/1814478.html 以下题解为转载代码自己写的: zoj2676 胡伯涛论文& ...

  7. 【HDU 5855】Less Time, More profit(网络流、最小割、最大权闭合子图)

    Less Time, More profit Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/O ...

  8. HDU 2676 Network Wars 01分数规划,最小割 难度:4

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1676 对顶点i,j,起点s=1,终点t=n,可以认为题意要求一组01矩阵use ...

  9. zoj 3165 (最小割,最大点权独立集)

    胡伯涛的<最小割模型在信息学竞赛中的应用>写的真牛. 这道题是选择一些男孩和女孩参加party,邀请的男孩女孩之间不能有 8g,图就是个明显的二分图,就是选择一些点之间没有8g关系,就是二 ...

随机推荐

  1. Mysql相关函数使用和总结(liet、right、substring、substring_index)

    一.字段截取 1.从左开始截取字符串 用法:left(str,length),即:leift(被截取字符串,截取长度) 列子:select left(‘www.baidu.com’,8) 结果:www ...

  2. 界面切换动画(CATransition实现 )

    调用 // CATransition动画实现 [self pushWithAnimationType:@"fade"]; - (void)pushWithAnimationType ...

  3. C-晾衣服

    链接:https://ac.nowcoder.com/acm/contest/892/C 题意: 鸡尾酒从杭州回来,囤积了许多衣服,洗好之后,他发现晾衣服是一件麻烦的事. 晾衣绳的长度只有L,而鸡尾酒 ...

  4. python大战机器学习——聚类和EM算法

    注:本文中涉及到的公式一律省略(公式不好敲出来),若想了解公式的具体实现,请参考原著. 1.基本概念 (1)聚类的思想: 将数据集划分为若干个不想交的子集(称为一个簇cluster),每个簇潜在地对应 ...

  5. Jmeter将JDBC Request查询结果作为下一个接口参数方法

    现在有一个需求,从数据库tieba_info表查出rank小于某个值的username和count(*),然后把所有查出来的username和count(*)作为参数值,用于下一个接口. tieba_ ...

  6. NetCore组件

    NetCore之组件写法 本章内容和大家分享的是Asp.NetCore组件写法,在netcore中很多东西都以提供组件的方式来使用,比如MVC架构,Session,Cache,数据库引用等: 这里我也 ...

  7. springboot启动提示缺少数据源

    If you want an embedded database please put a supported one on the classpath. If you have database s ...

  8. plsql连接远程数据库快捷方式

    不用修改任何文件就可以直接连接远程数据库

  9. Flask 学习系列(三)---Jinjia2使用过滤器

    再Jinjia2中过滤器是一种转变变量输出内容的技术.··过滤器通过管道符号“|与变量链接,并且可以通过圆括号传递参数” .举例说明: {{my_variable|default('my_variab ...

  10. 使用 xib 设置 button 等款等高

    很多时候需要使用平分的控件来布局,当然xib中可以之间使用 UIToolBar 使用 UIBarButtonItem 添加弹簧即可完成平均分布 但是,直接使用 button 也可以实现平均布局