Input
第一行一个正整数N。
第二行共包括N个正整数,第 个正整数表示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
题解
可以证明,任意两个偶数满足2
两个奇数满足1
(2a+1)^2+(2b+1)^2=2(2a^2+2b^2+2a+2b+1)
一定不是完全平方数
所以可以用最小割解决此题
连向S表示选择偶数,连向T表示选择奇数,
因为两个奇数,两个偶数都有一些奇怪的性质,如上,
然后如果两个都不满足,那么就连一条边,表示只能选其中一个。
1 #include<cstring> 2 #include<cmath> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstdio> 6 #include<queue> 7 8 #define ll long long 9 #define inf 2000000007 10 #define N 1007 11 #define M 1500007 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 17 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 21 int ans,n,S,T; 22 int a[N],b[N]; 23 int cnt,hed[N],nxt[M],rea[M],val[M],cur[N]; 24 int dis[N]; 25 26 void add(int u,int v,int w) 27 { 28 nxt[++cnt]=hed[u]; 29 hed[u]=cnt; 30 rea[cnt]=v; 31 val[cnt]=w; 32 } 33 void add_two_way(int u,int v,int w){add(u,v,w),add(v,u,0);} 34 ll sqr(ll x){return x*x;} 35 int gcd(int a,int b){return b?gcd(b,a%b):a;} 36 bool check(int x,int y) 37 { 38 // cout<<x<<" "<<y<<endl; 39 ll sum=sqr(a[x])+sqr(a[y]),sum1=(ll)sqrt(sum); 40 if (sqr(sum1)!=sum) return true; 41 if (gcd(a[x],a[y])>1) return true; 42 // cout<<x<<" "<<y<<endl; 43 return false; 44 } 45 bool bfs() 46 { 47 for (int i=S;i<=T;i++)dis[i]=-1; 48 dis[S]=0;queue<int>q;q.push(S); 49 while(!q.empty()) 50 { 51 int u=q.front();q.pop(); 52 for (int i=hed[u];i!=-1;i=nxt[i]) 53 { 54 int v=rea[i],w=val[i]; 55 if (w==0||dis[v]!=-1)continue; 56 dis[v]=dis[u]+1; 57 if (v==T)return 1; 58 q.push(v); 59 } 60 } 61 return 0; 62 } 63 int dfs(int u,int MX) 64 { 65 if (u==T||MX==0)return MX; 66 int res=0; 67 for (int i=cur[u];i!=-1;i=nxt[i]) 68 { 69 int v=rea[i],w=val[i]; 70 if (dis[v]!=dis[u]+1)continue; 71 int x=dfs(v,min(MX,w)); 72 cur[u]=i,res+=x,MX-=x; 73 val[i]-=x,val[i^1]+=x; 74 if (!MX)break; 75 } 76 if (!res)dis[u]=-1; 77 return res; 78 } 79 void dinic() 80 { 81 // cout<<"ans="<<ans<<endl; 82 while(bfs()) 83 { 84 // cout<<2<<endl; 85 for (int i=S;i<=T;i++)cur[i]=hed[i]; 86 ans-=dfs(S,inf); 87 // cout<<3<<endl; 88 } 89 } 90 int main() 91 { 92 freopen("fzy.in","r",stdin); 93 freopen("fzy.out","w",stdout); 94 95 cnt=1;memset(hed,-1,sizeof(hed)); 96 n=read(); 97 for (int i=1;i<=n;i++)a[i]=read(); 98 for (int i=1;i<=n;i++)b[i]=read(),ans+=b[i]; 99 S=0,T=n+1; 100 for (int i=1;i<=n;i++) 101 if (a[i]%2==0) add_two_way(S,i,b[i]); 102 else add_two_way(i,T,b[i]); 103 for (int i=1;i<=n;i++) 104 for (int j=1;j<=n;j++) 105 if ((a[i]%2==0)&&(a[j]%2==1)) 106 if (!check(i,j)) add_two_way(i,j,inf); 107 dinic(); 108 printf("%d",ans); 109 }