【BZOJ】【3158】千钧一发

网络流/最小割



  这题跟BZOJ 3275限制条件是一样的= =所以可以用相同的方法去做……只要把边的容量从a[i]改成b[i]就行了~

(果然不加当前弧优化要略快一点)

  1 /**************************************************************
  2     Problem: 3158
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:196 ms
  7     Memory:13028 kb
  8 ****************************************************************/
  9
 10 //BZOJ 3158
 11 #include<cmath>
 12 #include<vector>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<cstdlib>
 16 #include<iostream>
 17 #include<algorithm>
 18 #define rep(i,n) for(int i=0;i<n;++i)
 19 #define F(i,j,n) for(int i=j;i<=n;++i)
 20 #define D(i,j,n) for(int i=j;i>=n;--i)
 21 #define pb push_back
 22 using namespace std;
 23 inline int getint(){
 24     int v=0,sign=1; char ch=getchar();
 25     while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
 26     while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
 27     return v*sign;
 28 }
 29 const int N=1100,M=1000000,INF=~0u>>2;
 30 typedef long long LL;
 31 /******************tamplate*********************/
 32 int n,m,tot,ans,a[N],b[N];
 33 struct edge{int to,v;};
 34 int gcd(int a,int b){return b ? gcd(b,a%b) : a;}
 35 bool judge(LL a,LL b){
 36     LL s=a*a+b*b;
 37     LL q=sqrt(s);
 38     if (q*q!=s) return 0;
 39     if (gcd(a,b)!=1) return 0;
 40     return 1;
 41 }
 42 struct Net{
 43     edge E[M];
 44     int head[N],next[M],cnt;
 45     void ins(int x,int y,int v){
 46         E[++cnt]=(edge){y,v};
 47         next[cnt]=head[x]; head[x]=cnt;
 48     }
 49     void add(int x,int y,int v){
 50         ins(x,y,v); ins(y,x,0);
 51     }
 52     int s,t,d[N],Q[N];
 53     void init(){
 54         n=getint(); cnt=1;
 55         tot=ans=0;
 56         s=0; t=n+1;
 57         F(i,1,n) a[i]=getint();
 58         F(i,1,n){
 59             b[i]=getint();tot+=b[i];
 60             if (a[i]&1) add(s,i,b[i]);
 61             else add(i,t,b[i]);
 62         }
 63         F(i,1,n) if (a[i]&1)
 64             F(j,1,n) if((a[j]&1)==0)
 65                 if (judge(a[i],a[j])) add(i,j,INF);
 66     }
 67     bool mklevel(){
 68         memset(d,-1,sizeof d);
 69         d[s]=0;
 70         int l=0,r=-1;
 71         Q[++r]=s;
 72         while(l<=r){
 73             int x=Q[l++];
 74             for(int i=head[x];i;i=next[i])
 75                 if (d[E[i].to]==-1 && E[i].v){
 76                     d[E[i].to]=d[x]+1;
 77                     Q[++r]=E[i].to;
 78                 }
 79         }
 80         return d[t]!=-1;
 81     }
 82     int dfs(int x,int a){
 83         if (x==t) return a;
 84         int flow=0;
 85         for(int i=head[x];i && flow<a;i=next[i])
 86             if (E[i].v && d[E[i].to]==d[x]+1){
 87                 int f=dfs(E[i].to,min(a-flow,E[i].v));
 88                 E[i].v-=f;
 89                 E[i^1].v+=f;
 90                 flow+=f;
 91             }
 92         if (!flow) d[x]=-1;
 93         return flow;
 94     }
 95     void Dinic(){
 96         while(mklevel())
 97             ans+=dfs(s,INF);
 98     }
 99 }G1;
100
101 int main(){
102 #ifndef ONLINE_JUDGE
103     freopen("3158.in","r",stdin);
104     freopen("3158.out","w",stdout);
105 #endif
106     G1.init(); G1.Dinic();
107     printf("%d\n",tot-ans);
108     return 0;
109 }

时间: 2024-10-12 13:05:52

【BZOJ】【3158】千钧一发的相关文章

bzoj 3158 千钧一发(最小割)

3158: 千钧一发 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 767  Solved: 290[Submit][Status][Discuss] Description Input 第一行一个正整数N. 第二行共包括N个正整数,第 个正整数表示Ai. 第三行共包括N个正整数,第 个正整数表示Bi. Output 共一行,包括一个正整数,表示在合法的选择条件下,可以获得的能量值总和的最大值. Sample Input 4 3 4 5 12 9

bzoj 3158: 千钧一发

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define M 200009 7 #define inf 2139062143 8 using namespace std; 9 int cnt=1,n,m,S,T,d[M],q[2*M],f[M],head[M],next[10*M],u[

BZOJ 3275 Number &amp;&amp; 3158 千钧一发 最小割

题目大意:给出一些数字,要求选出一些数字并保证所有数字和最大,要求这其中的数字任意两个至少满足一个条件,则不能同时被选:1.这两个数的平方和是完全平方数.2.gcd(a,b) = 1. 思路:我们可以将奇数和偶数分开来讨论,奇数不满足1,偶数不满足2,所以奇数和奇数,偶数和偶数不会互相影响.之后O(n^2)的讨论其他数字对,有影响就连边,流量正无穷,最后跑最小割最最大获利. CODE: #define _CRT_SECURE_NO_WARNINGS #include <cmath> #incl

BZOJ 3275: Number

3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discuss] Description 有N个正整数,需要从中选出一些数,使这些数的和最大. 若两个数a,b同时满足以下条件,则a,b不能同时被选 1:存在正整数C,使a*a+b*b=c*c 2:gcd(a,b)=1 Input 第一行一个正整数n,表示数的个数. 第二行n个正整数a1,a2,?an. Out

【BZOJ-3275&amp;3158】Number&amp;千钧一发 最小割

3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 748  Solved: 316[Submit][Status][Discuss] Description 有N个正整数,需要从中选出一些数,使这些数的和最大.若两个数a,b同时满足以下条件,则a,b不能同时被选1:存在正整数C,使a*a+b*b=c*c2:gcd(a,b)=1 Input 第一行一个正整数n,表示数的个数. 第二行n个正整数a1,a2,?an. Output

bzoj3158: 千钧一发(最小割)

3158: 千钧一发 题目:传送门 题解: 这是一道很好的题啊...极力推荐 细看题目:要求一个最大价值,那么我们可以转换成求损失的价值最小 那很明显就是最小割的经典题目啊?! 但是这里两个子集的分化并不明显...GG 耐心一点,从题目的要求再入手: 对于第二个要求,如果两点的a值都为偶数,那么肯定满足 那如果两个数都为奇数的话,也必定满足要求一,证明如下: 1.一个奇数的平方%4为1,一个偶数的平方%4为0 2.两个奇数的平方和%4为2 3.如果两个奇数的平方和是一个奇数的平方,那么%4应该为

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max

bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛

对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b). Input 第一行一个数T,表示询问数. 接下来T行,每行两个数a,b,表示一个询问. Output 对于每一个询问,输出一行一个非负整数作为回答. Sample Input 4 7558588 9653114 6514903 445

【BZOJ】[HNOI2009]有趣的数列

[算法]Catalan数 [题解] 学了卡特兰数就会啦>_<! 因为奇偶各自递增,所以确定了奇偶各自的数字后排列唯一. 那么就是给2n个数分奇偶了,是不是有点像入栈出栈序呢. 将做偶数标为-1,做奇数标为+1,显然当偶数多于奇数时不合法,因为它压不住后面的奇数. 然后其实这种题目,打表就可知啦--QAQ 然后问题就是求1/(n+1)*C(2n,n)%p了,p不一定是素数. 参考bzoj礼物的解法. 看到网上清一色的素数筛+分解质因数解法,不解了好久,感觉写了假的礼物-- 后来觉得礼物的做法才比