没错,最近在做网络流~这道题的确不错滴
最小割模型,偶数和奇数,一个连源点,一个连汇点
为什么?
1、偶数间明显符合第二个条件
2、奇数间,设一个为2n+1,另一个2m+1然后写一写就知道啦。
具体的可以看看hwzer的和硕哥的点击打开链接
注意好判平方的大小还有两个装置间的条件
贴个代码:
#include
#include
#include
#include
#include
#include
#include
#define Max 0x7fffffff #define me(a,x) memset(a,x,sizeof a) using namespace std; typedef long long LL; struct node { int x,y,c,next; }a[5010000]; int len,first[1100]; void ins(int x,int y,int c) { a[++len].x=x,a[len].y=y,a[len].c=c; a[len].next=first[x],first[x]=len; a[++len].x=y,a[len].y=x,a[len].c=0; a[len].next=first[y],first[y]=len; } queue
q; int h[1010],t; bool spfa() { for(int i=0;i<=t;i++)h[i]=0; h[0]=1; q.push(0); while(!q.empty()) { int x=q.front(); q.pop(); for(int k=first[x];k;k=a[k].next) { int y=a[k].y; if(!h[y] && a[k].c) { h[y]=h[x]+1; q.push(y); } } } return h[t]>0; } int dfs(int x,int f) { if(x==t)return f; int de=0; for(int k=first[x];k;k=a[k].next) { int y=a[k].y; if(a[k].c && h[y]==h[x]+1) { int mf=dfs(y,min(a[k].c,f-de)); a[k].c-=mf,a[k^1].c+=mf,de+=mf; if(de==f)return f; } } if(!de)h[x]=0; return de; } int l[1010],p[1010]; int gcd(int x,int y) { if(y==0)return x; return gcd(y,x%y); } bool check(LL x,LL y) { LL c=(x*x)+(y*y),cc=sqrt(c); if(cc*cc!=c)return 0; if(gcd(x,y)>1)return 0; return 1; } int main() { int n,x,y,i,j; scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d",&l[i]); for(i=1;i<=n;i++)scanf("%d",&p[i]); t=n+1; int s=0; len=1; me(first,0); for(i=1;i<=n;i++) { s+=p[i]; if(l[i]&1)ins(0,i,p[i]); else ins(i,t,p[i]); for(j=1;j<=n;j++) if( (l[i]&1)&& ((l[j]&1)==0) && check(l[i],l[j]) ) ins(i,j,Max); } while(spfa())s-=dfs(0,Max); printf("%d\n",s); return 0; }