bzoj3158 千钧一发
个正整数表示Ai。
第三行共包括N个正整数,第 个正整数表示Bi。 Output
共一行,包括一个正整数,表示在合法的选择条件下,可以获得的能量值总和的最大值。 Sample Input
4 3 4 5 12 9 8 30 9
Sample Output
39
HINT
1<=N<=1000,1<=Ai,Bi<=10^6
这题最小割需要用一部分数学知识证明首先我肯定希望全部选上 但是总有不可以的对吧 但是可以知道偶数一定满足第二个条件 因为gcd至少是2 那么奇数一定满足条件1 如何证? 设a,b为奇数 c为整数 a2+b2=c2 设a=2×k1+1,b=2×k2+1 那么 4k12+4k1+1+4k22+4k2+1=c24×{k12+k1+k22+k2}+2=c2那么可以看出因为2是质数并且c2可以整除2 那么c也可以整除2 所以不妨假设c=2×k 那么原式可以看成4×{k12+k1+k22+k2}+2=4×k2 两边同除以4 发现k12+k1+k22+k2+12=k2
#include#include#include#include#include#define N 1100#define inf 0x3f3f3f3fusing namespace std;inline char gc(){ static char now[1<<16],*S,*T; if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S)return EOF;} return *S++;}inline int read(){ int x=0;char ch=gc(); while(ch<'0'||ch>'9') ch=gc(); while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();} return x;}int n,h[N],level[N],a[N],cur[N],T,b[N],num=1;struct node{ int x,y,z,next;}data[700000];inline void insert1(int x,int y,int z){ data[++num].y=y;data[num].z=z;data[num].next=h[x];h[x]=num;data[num].x=x; data[++num].y=x;data[num].z=0;data[num].next=h[y];h[y]=num;data[num].x=y;}inline bool bfs(){ queueq;memset(level,0,sizeof(level));level[0]=1;q.push(0); while(!q.empty()){ int x=q.front();q.pop(); for (int i=h[x];i;i=data[i].next){ int y=data[i].y,z=data[i].z; if(level[y]||!z) continue;level[y]=level[x]+1;q.push(y);if (y==T) return 1; } }return 0;}inline int dfs(int x,int s){ if (x==T) return s;int ss=s,tt=h[x]; for (int i=cur[x];i;i=data[i].next){ int y=data[i].y,z=data[i].z; if (level[x]+1==level[y]&&z){ int xx=dfs(y,min(s,z));if (!xx) level[y]=0;tt=i; s-=xx;data[i].z-=xx;data[i^1].z+=xx;if (!s) {cur[x]=i;return ss;} } }cur[x]=tt;return ss-s;}inline int gcd(int x,int y){ if (!y) return x;return gcd(y,x%y);}int main(){ freopen("bzoj3158.in","r",stdin); n=read();int sum=0;int ans=0;T=n+1; for (int i=1;i<=n;++i) a[i]=read(); for (int i=1;i<=n;++i) {b[i]=read(),sum+=b[i];if (a[i]&1) insert1(0,i,b[i]);else insert1(i,T,b[i]);} for (int i=1;i<=n;++i){ if ((a[i]&1)==0) continue; for (int j=1;j<=n;++j){ if (a[j]&1) continue;if (gcd(a[i],a[j])!=1) continue; long long x2=(long long)a[i]*a[i]+(long long)a[j]*a[j],xx=sqrt(x2);if (xx*xx==x2) insert1(i,j,inf); } } //for (int i=2;i<=num;++i) printf("%d %d %d\n",data[i].x,data[i].y,data[i].z); while(bfs()) memcpy(cur,h,sizeof(h)),ans+=dfs(0,inf); printf("%d\n",sum-ans); return 0;}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~