• 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
    ",sum-ans);
    96     return 0;
    97 }
  • 相关阅读:
    GDB常用命令总结
    进程使用的文件描述符fd值达到最大值引起的问题
    RedHat静态Ip地址配置
    Hotspot JVM默认垃圾收集器
    JVM常用参数及调优
    spring-boot定制和优化内嵌的Tomcat
    平面设计技能
    docker 虚悬镜像
    Linux 常用命令
    同步、异步、阻塞、非阻塞
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8659290.html
Copyright © 2020-2023  润新知