【传送门:BZOJ3158


简要题意:

  给出n个机器,每个机器有a[i]基础值和b[i]价值

  选出一部分机器使得这些机器里面两两至少满足以下两种条件之一:

  1.a[i]2+a[j]2!=T2(T为正整数)

  2.gcd(a[i],a[j])>1

  求出能达到要求的最大价值


题解:

  神最小割

  要求一个最大价值,那么我们可以转换成求损失的价值最小

  但是这里两个子集的分化并不明显

  对于第二个要求,如果两点的a值都为偶数,那么肯定满足

  那如果两个数都为奇数的话,也必定满足要求一,证明如下:

  1、一个奇数的平方%4为1,一个偶数的平方%4为0

  2、两个奇数的平方和%4为2

  3、如果两个奇数的平方和是一个奇数的平方,那么%4应该为1,不符合

  4、如果两个奇数的平方和是一个偶数的平方,那么%4应该为0,不符合

  这样子思考的话,两个子集的分化就较为明显了:

  st向a值为奇数的相连,a值为偶数的向ed相连,容量都为b值;

  这样子所形成的两个子集里面的点一定都是符合要求的。

  最后一步,也是最关键的一步:

  两个子集之间两两匹配,如果当前匹配的两个点是不符合要求的,就将这两个点相连,容量为无限大。

  跑最小割,割出来的边就是损失价值的最小值 用sum-最小割就是答案

  by Cherish_OI

  注意要加long long


参考代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cstdlib>
  5. #include<cmath>
  6. using namespace std;
  7. typedef long long LL;
  8. struct node
  9. {
  10. int x,y,next,other;LL c;
  11. }a[];int len,last[];
  12. void ins(int x,int y,LL c)
  13. {
  14. int k1=++len,k2=++len;
  15. a[k1].x=x;a[k1].y=y;a[k1].c=c;
  16. a[k1].next=last[x];last[x]=k1;
  17. a[k2].x=y;a[k2].y=x;a[k2].c=;
  18. a[k2].next=last[y];last[y]=k2;
  19. a[k1].other=k2;
  20. a[k2].other=k1;
  21. }
  22. int h[],list[],st,ed;
  23. bool bt_h()
  24. {
  25. memset(h,,sizeof(h));h[st]=;
  26. list[]=st;
  27. int head=,tail=;
  28. while(head!=tail)
  29. {
  30. int x=list[head];
  31. for(int k=last[x];k;k=a[k].next)
  32. {
  33. int y=a[k].y;
  34. if(a[k].c>&&h[y]==)
  35. {
  36. h[y]=h[x]+;
  37. list[tail++]=y;
  38. }
  39. }
  40. head++;
  41. }
  42. if(h[ed]==) return false;
  43. else return true;
  44. }
  45. LL findflow(int x,LL f)
  46. {
  47. if(x==ed) return f;
  48. int s=,t;
  49. for(int k=last[x];k;k=a[k].next)
  50. {
  51. int y=a[k].y;
  52. if(a[k].c>&&h[y]==(h[x]+)&&f>s)
  53. {
  54. t=findflow(y,min(a[k].c,f-s));
  55. s+=t;
  56. a[k].c-=t;a[a[k].other].c+=t;
  57. }
  58. }
  59. if(s==) h[x]=;
  60. return s;
  61. }
  62. LL gcd(LL a,LL b)
  63. {
  64. if(a==) return b;
  65. else return gcd(b%a,a);
  66. }
  67. LL A[],B[];
  68. bool check(LL x,LL y)
  69. {
  70. LL c=sqrt(x*x+y*y);
  71. if(c*c!=x*x+y*y) return false;
  72. if(gcd(x,y)>) return false;
  73. return true;
  74. }
  75. int main()
  76. {
  77. int n;
  78. scanf("%d",&n);
  79. st=;ed=n+;
  80. len=;memset(last,,sizeof(last));
  81. LL sum=;
  82. for(int i=;i<=n;i++)
  83. {
  84. scanf("%lld",&A[i]);
  85. sum+=A[i];
  86. if(A[i]%==) ins(st,i,A[i]);
  87. else ins(i,ed,A[i]);
  88. }
  89. for(int i=;i<=n;i++)
  90. {
  91. for(int j=;j<=n;j++)
  92. {
  93. if(check(A[i],A[j])==true&&(A[i]%==)&&(A[j]%==))
  94. {
  95. ins(i,j,);
  96. }
  97. }
  98. }
  99. while(bt_h()==true) sum-=findflow(st,);
  100. printf("%lld\n",sum);
  101. return ;
  102. }

BZOJ3158: 千钧一发的更多相关文章

  1. BZOJ3158 千钧一发(最小割)

    可以看做一些物品中某些互相排斥求最大价值.如果这是个二分图的话,就很容易用最小割了. 观察其给出的条件间是否有什么联系.如果两个数都是偶数,显然满足条件二:而若都是奇数,则满足条件一,因为式子列出来发 ...

  2. [bzoj3158]千钧一发——二分图+网络流

    题目 传送门 题解 很容易建立模型,如果两个点不能匹配,那么连一条边,那么问题就转化为了求一个图上的最大点权独立集. 而我们可以知道: 最大点权独立集+最小点权覆盖集=总权值. 同时最小点权覆盖在一般 ...

  3. 【BZOJ3158】千钧一发 最小割

    [BZOJ3158]千钧一发 Description Input 第一行一个正整数N. 第二行共包括N个正整数,第 个正整数表示Ai. 第三行共包括N个正整数,第 个正整数表示Bi. Output 共 ...

  4. 【bzoj3158】 千钧一发

    http://www.lydsy.com/JudgeOnline/problem.php?id=3158 (题目链接) 题意 给出n个装置,每个装置i有一个特征值a[i]和一个能量值b[i],要求选出 ...

  5. bzoj3158&3275: 千钧一发(最小割)

    3158: 千钧一发 题目:传送门 题解: 这是一道很好的题啊...极力推荐 细看题目:要求一个最大价值,那么我们可以转换成求损失的价值最小 那很明显就是最小割的经典题目啊?! 但是这里两个子集的分化 ...

  6. 【BZOJ-3275&3158】Number&千钧一发 最小割

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 748  Solved: 316[Submit][Status][Discus ...

  7. BZOJ 3158: 千钧一发

    3158: 千钧一发 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1201  Solved: 446[Submit][Status][Discuss ...

  8. 【BZOJ】【3158】千钧一发

    网络流/最小割 这题跟BZOJ 3275限制条件是一样的= =所以可以用相同的方法去做……只要把边的容量从a[i]改成b[i]就行了- (果然不加当前弧优化要略快一点) /************** ...

  9. bzoj 3158 千钧一发(最小割)

    3158: 千钧一发 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 767  Solved: 290[Submit][Status][Discuss] ...

随机推荐

  1. python继承 super()

    写这篇博文,始于以下问题的探究: #coding:utf-8 class A(object): def __init__(self): print 'enter A' print 'leave A' ...

  2. [arc076e]connected?

    题意: 给出一个$R\times C$的棋盘,其中$1$到$N$之间的每个正整数都会在棋盘上出现两次,第$i$个数出现的位置是$(X_{i,1},Y_{i,1})$和$(X_{i,2},Y_{i,2} ...

  3. HTTP——学习笔记(6)https

    HTTP+加密+认证+完整性保护=HTTPS HTTP是一种新协议吗?: 不是,HTTPS只是HTTP通信接口部分用SSL和TLS协议代替而已 HTTP中,身处应用层的HTTP直接和TCP通信.而在使 ...

  4. [转载]深入Java单例模式

    在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单例设计模式详细的探讨一下.   所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在 ...

  5. 传纸条 NOIP2008 洛谷1006 二维dp

    二维dp 扯淡 一道比较基本的入门难度的二维dp,类似于那道方格取数,不过走过一次的点下次不能再走(看提交记录里面好像走过一次的加一次a[i][j]的也AC了,,),我记得当年那道方格取数死活听不懂, ...

  6. 洛谷 P1990 覆盖墙壁

    P1990 覆盖墙壁 题目描述 你有一个长为N宽为2的墙壁,给你两种砖头:一个长2宽1,另一个是L型覆盖3个单元的砖头.如下图: 0 0 0 00 砖头可以旋转,两种砖头可以无限制提供.你的任务是计算 ...

  7. 一 Storm 基础

     1  Storm 分布式计算结构称为 Topology (拓扑)         Topology 由 stream(数据流).spout(数据流的生成者).bolt(运算)组成.          ...

  8. 2015合肥网络赛 HDU 5489 Removed Interval LIS+线段树(树状数组)

    HDU 5489 Removed Interval 题意: 求序列中切掉连续的L长度后的最长上升序列 思路: 从前到后求一遍LIS,从后往前求一遍LDS,然后枚举切开的位置i,用线段树维护区间最大值, ...

  9. 《剑指offer》调整数组顺序使奇数位于偶数前面

    一.题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 二.输入描述 ...

  10. 《剑指offer》二进制中1的个数

    一.题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 二.牛客网提供的框架 class Solution { public: int NumberOf1(int n) { } ...