bzoj3275: Number(最小割)
Posted CHerish_OI
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3275: Number(最小割)相关的知识,希望对你有一定的参考价值。
3275: Number
题目:传送门
题解:
双倍经验@bzoj3158
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 #define qread(x) x=read() 7 using namespace std; 8 const int inf=999999999; 9 int n,st,ed,sum; 10 int A[11000],B[11000]; 11 struct node 12 { 13 int x,y,c,next,other; 14 }a[3100000];int len,last[3100]; 15 void ins(int x,int y,int c) 16 { 17 int k1,k2; 18 k1=++len; 19 a[len].x=x;a[len].y=y;a[len].c=c; 20 a[len].next=last[x];last[x]=len; 21 22 k2=++len; 23 a[len].x=y;a[len].y=x;a[len].c=0; 24 a[len].next=last[y];last[y]=len; 25 26 a[k1].other=k2; 27 a[k2].other=k1; 28 } 29 int list[3100],h[3100],head,tail; 30 bool bt_h() 31 { 32 memset(h,0,sizeof(h));h[st]=1; 33 list[1]=st;head=1;tail=2; 34 while(head!=tail) 35 { 36 int x=list[head]; 37 for(int k=last[x];k;k=a[k].next) 38 { 39 int y=a[k].y; 40 if(h[y]==0 && a[k].c>0) 41 { 42 h[y]=h[x]+1; 43 list[tail++]=y; 44 } 45 } 46 head++; 47 } 48 if(h[ed]>0)return true; 49 return false; 50 } 51 int find_flow(int x,int flow) 52 { 53 if(x==ed)return flow; 54 int s=0,t; 55 for(int k=last[x];k;k=a[k].next) 56 { 57 int y=a[k].y; 58 if(h[y]==h[x]+1 && a[k].c>0 && flow>s) 59 { 60 s+=t=find_flow(y,min(a[k].c,flow-s)); 61 a[k].c-=t;a[a[k].other].c+=t; 62 } 63 } 64 if(s==0)h[x]=0; 65 return s; 66 } 67 int gcd(int x,int y) {if(x>y)swap(x,y);if(x==0)return y;return gcd(y%x,x);} 68 bool pd(int x,int y) 69 { 70 int t=int(sqrt(double(x*x+y*y))); 71 if(t*t!=x*x+y*y)return true; 72 if(gcd(x,y)>1)return true; 73 return false; 74 } 75 int main() 76 { 77 freopen("number.in","r",stdin); 78 freopen("number.out","w",stdout); 79 sum=0; 80 scanf("%d",&n); 81 len=0;memset(last,0,sizeof(last)); 82 for(int i=1;i<=n;i++){scanf("%d",&B[i]);sum+=B[i];} 83 st=n+1;ed=st+1; 84 for(int i=1;i<=n;i++) 85 { 86 if(B[i]%2==1)ins(st,i,B[i]); 87 else ins(i,ed,B[i]); 88 } 89 for(int i=1;i<=n;i++) 90 for(int j=1;j<=n;j++)if(i!=j) 91 if((B[i]%2==1) && (B[j]%2==0) && pd(B[i],B[j])==false) 92 ins(i,j,999999999); 93 int ans=0; 94 while(bt_h())ans+=find_flow(st,999999999); 95 printf("%d\\n",sum-ans); 96 return 0; 97 }
以上是关于bzoj3275: Number(最小割)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj4519: [Cqoi2016]不同的最小割(分治最小割)