bzoj3275: Number
最小割。。。然后推一下可知不能的情况必定为一奇一偶,于是s->奇->偶->t。跑最小割即可。
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define REP(i,s,t) for(int i=s;i<=t;i++) #define op() clr(head,0);pt=edges; #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar();bool f=true; while(!isdigit(c)) { if(c=='-') f=false;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=3005; const int maxn=6000005; const int inf=0x7f7f7f7f; struct edge{ int to,cap;edge *next,*rev; }; edge edges[maxn],*pt,*head[nmax],*p[nmax],*cur[nmax]; int cnt[nmax],h[nmax],g[nmax]; void add(int u,int v,int w){ pt->to=v;pt->cap=w;pt->next=head[u];head[u]=pt++; } void adde(int u,int v,int w){ add(u,v,w);add(v,u,0);head[u]->rev=head[v];head[v]->rev=head[u]; } int maxflow(int s,int t,int n){ clr(cnt,0);cnt[0]=n;clr(h,0); int flow=0,a=inf,x=s;edge *e; while(h[s]<n){ for(e=cur[x];e;e=e->next) if(e->cap>0&&h[x]==h[e->to]+1) break; if(e){ a=min(a,e->cap);p[e->to]=cur[x]=e;x=e->to; if(x==t){ while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to; flow+=a,a=inf; } }else{ if(!--cnt[h[x]]) break; h[x]=n; for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e; cnt[h[x]]++; if(x!=s) x=p[x]->rev->to; } } return flow; } int gcd(int x,int y){ return y==0?x:gcd(y,x%y); } bool check(int x,int y){ if(gcd(x,y)!=1) return false; int tmp=x*x+y*y,temp=sqrt(tmp); if(temp*temp==tmp) return true; return false; } int main(){ op(); int n=read(),s=0,t=n+1,ans=0; rep(i,n){ g[i]=read();ans+=g[i]; g[i]%2?adde(s,i,g[i]):adde(i,t,g[i]); } rep(i,n) if(g[i]%2) rep(j,n) if(!(g[j]%2)) if(check(g[i],g[j])) adde(i,j,inf); /*REP(i,s,t) { qwq(i) printf("%d ",o->to);printf("\n"); }*/ printf("%d\n",ans-maxflow(s,t,t+1)); return 0; }
3275: Number
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 778 Solved: 329
[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。
Output
最大的和。
Sample Input
5
3 4 5 6 7
3 4 5 6 7
Sample Output
22
HINT
n<=3000。