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(最小割)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3275 Number

BZOJ 3275: Number

bzoj4519: [Cqoi2016]不同的最小割(分治最小割)

bzoj2229 Zjoi2011—最小割

最小割分治(最小割树):BZOJ2229 && BZOJ4519

bzoj4435: [Cerc2015]Juice Junctions(最小割树+hash)