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. How to install your SSL Certificate to your Windows Server

    Installation: Open the ZIP file containing your certificate. Save the file named your_domain_name.ce ...

  2. vue教程2-组件化开发

    全局组件 <div id="app"> <cs1></cs1> </div> <script> Vue.componen ...

  3. python大战机器学习——人工神经网络

    人工神经网络是有一系列简单的单元相互紧密联系构成的,每个单元有一定数量的实数输入和唯一的实数输出.神经网络的一个重要的用途就是接受和处理传感器产生的复杂的输入并进行自适应性的学习,是一种模式匹配算法, ...

  4. js弹框怎么获得父页面的元素

    js获取父页面的元素可以用$(window.parent.document).find("#customer_id").val();这里的customer_id表示父页面某一个元素 ...

  5. 30道python真实面试题(搜集到的,看看其实都是基础)

    1.一行代码实现1-100之间和 In [1]: sum(range(0,101)) Out[1]: 5050 2.如何在一个函数内部修改全局变量 利用global修改全局变量 In [2]: a = ...

  6. GDPR(Cookie处理)

    GDPR(Cookie处理) https://www.cnblogs.com/GuZhenYin/p/9154447.html 前言 时间一晃 ASP.NET Core已经迭代到2.1版本了. 迫不及 ...

  7. HDU 5875 H - Function 用单调栈水过了

    http://acm.hdu.edu.cn/showproblem.php?pid=5875 单调栈,预处理to[i]表示第一个比a[i]小的数字,一直跳就可以. 这题是数据水而已. 这里学习下单调栈 ...

  8. HDU 5883 F - The Best Path 欧拉通路 & 欧拉回路

    给定一个图,要求选一个点作为起点,然后经过每条边一次,然后把访问过的点异或起来(访问一次就异或一次),然后求最大值. 首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为 ...

  9. MapReduce错误之Error: java.lang.RuntimeException: java.lang.NoSuchMethodException的解决方法

    今天跑MapReduce项目的时候遇到了这个问题,日志如下所示: // :: DEBUG ipc.ProtobufRpcEngine: Call: getDiagnostics took 19ms E ...

  10. c#的Lambda 表达式

    首先看官方的说法: Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数. Lambda 表达式 ...