zoukankan      html  css  js  c++  java
  • BZOJ 3158 千钧一发 (最大流->二分图带权最大独立集)

    题面:BZOJ传送门

    和方格取数问题很像啊

    但这道题不能像网格那样黑白染色构造二分图,所以考虑拆点建出二分图

    我们容易找出数之间的互斥关系,在不能同时选的两个点之间连一条流量为$inf$的边

    由于我们是拆点建的图,所以对于两个点$x,y$,$x1$向$y2$连边,$y1$向$x2$连边,边权均为$inf$

    然后就是最大权闭合图的裸题了,源点$S$向所有$1$点连边,所有$2$点向汇点$T$连边,边权为$b_{i}$

    跑最大流。最终答案是$sum b_{i}-$最大流$/2$,$/2$是因为拆点求出的是$2$倍的最小割

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define N1 2010
     6 #define M1 1010000
     7 #define ll long long
     8 using namespace std;
     9 
    10 const int inf=0x3f3f3f3f;
    11 int gint()
    12 {
    13     int ret=0,fh=1; char c=getchar();
    14     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
    15     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
    16     return ret*fh;
    17 }
    18 int gcd(int x,int y){ if(!y) return x; return gcd(y,x%y); }
    19 struct Edge{
    20 int head[N1],to[M1<<1],nxt[M1<<1],flow[M1<<1],cte;
    21 void ae(int u,int v,int f)
    22 {
    23     cte++; to[cte]=v; nxt[cte]=head[u];
    24     head[u]=cte; flow[cte]=f;
    25 }
    26 }e;
    27 
    28 int n,m,hd,tl,S,T;
    29 int dep[N1],cur[N1],que[M1];
    30 int bfs()
    31 {
    32     int x,j,v;
    33     memset(dep,-1,(T+1)<<2); memcpy(cur,e.head,(T+1)<<2);
    34     hd=1,tl=0; que[++tl]=S; dep[S]=0;
    35     while(hd<=tl)
    36     {
    37         x=que[hd++];
    38         for(j=e.head[x];j;j=e.nxt[j])
    39         {
    40             v=e.to[j];
    41             if( e.flow[j]>0 && dep[v]==-1 )
    42                 dep[v]=dep[x]+1, que[++tl]=v;
    43         }
    44     }
    45     return dep[T]!=-1;
    46 }
    47 int dfs(int x,int limit)
    48 {
    49     int j,v,flow,ans=0;
    50     if(x==T||!limit) return limit;
    51     for(j=cur[x];j;j=e.nxt[j])
    52     {
    53         v=e.to[j]; cur[x]=j;
    54         if( dep[v]==dep[x]+1 && (flow=dfs(v,min(e.flow[j],limit))) )
    55         {
    56             e.flow[j]-=flow; limit-=flow;
    57             e.flow[j^1]+=flow; ans+=flow;
    58             if(!limit) break;
    59         }
    60     }
    61     return ans;
    62 }
    63 int Dinic()
    64 {
    65     int ans=0;
    66     while(bfs())
    67         ans+=dfs(S,inf);
    68     return ans;
    69 }
    70 
    71 int a[N1],b[N1];
    72 int main()
    73 {
    74     scanf("%d",&n); S=0; T=n+n+1;
    75     int i,j,sum=0,ans;ll k; e.cte=1;
    76     for(i=1;i<=n;i++) a[i]=gint();
    77     for(i=1;i<=n;i++) b[i]=gint(), sum+=b[i]; 
    78     for(i=1;i<=n;i++) for(j=1;j<=n;j++)
    79     {
    80         if(i==j) continue;
    81         if(gcd(a[i],a[j])>1) continue;
    82         k=sqrt(1ll*a[i]*a[i]+1ll*a[j]*a[j]);
    83         if(1ll*k*k!=1ll*a[i]*a[i]+1ll*a[j]*a[j]) continue;
    84         e.ae(i,j+n,inf); e.ae(j+n,i,0);
    85     }
    86     for(i=1;i<=n;i++) e.ae(S,i,b[i]), e.ae(i,S,0), e.ae(i+n,T,b[i]), e.ae(T,i+n,0);
    87     ans=Dinic();
    88     printf("%d
    ",sum-ans/2);
    89     bfs();
    90     S=T; bfs();
    91     return 0;
    92 }
  • 相关阅读:
    查看占用内存cpu top10
    free 详解
    find
    服务器硬件查看
    firewalld命令使用
    firewalld-zone概念介绍
    Jenkins rpm包安装
    攻击防御案例
    filebeat收集系统登陆日志
    nginx转换json格式
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10350313.html
Copyright © 2011-2022 走看看