• 解题:BZOJ 4808 马


    题面

    以前写过的题,翻出来学习网络流写二分图匹配,因为复杂度更优秀,$Dinic$是$O(sqrt(n)m)$哒~

    原点向左部点连流量为$1$的边,左部点向对应右部点连流量为$1$的边,右部点向汇点连流量为$1$的边,然后跑

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int B=205,N=40005,M=320005,inf=1e9;
     6 const int mov[8][2]={{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{1,-2},{-1,2},{-1,-2}};
     7 int T,n,m,s,t,f,b,t1,t2,rd,num,cnt,tot,ans;
     8 int noww[2*M],goal[2*M],flow[2*M];
     9 int p[N],pp[N],dep[N],que[N];
    10 int bro[B][B],mapp[B][B];
    11 int tonum(int x,int y)
    12 {
    13     return (x-1)*m+y;
    14 }
    15 bool check(int x,int y)
    16 {
    17     return x>=1&&x<=n&&y>=1&&y<=m; 
    18 }
    19 void link(int f,int t,int v)
    20 {
    21     noww[++cnt]=p[f],p[f]=cnt;
    22     goal[cnt]=t,flow[cnt]=v;
    23     noww[++cnt]=p[t],p[t]=cnt;
    24     goal[cnt]=f,flow[cnt]=0;
    25 }
    26 bool Layering(int st,int ed)
    27 {
    28     for(int i=1;i<=num;i++) pp[i]=p[i];
    29     memset(dep,-1,sizeof dep);
    30     dep[st]=0,que[f=b=0]=st;
    31     while(f<=b)
    32     {
    33         int tn=que[f++];
    34         for(int i=p[tn];i;i=noww[i])
    35             if(dep[goal[i]]==-1&&flow[i])
    36                 dep[goal[i]]=dep[tn]+1,que[++b]=goal[i];
    37     }
    38     return ~dep[ed];
    39 }
    40 int Augmenting(int nd,int ed,int mn)
    41 {
    42     if(nd==ed||!mn) return mn;
    43     int tmp=0,tep=0;
    44     for(int i=pp[nd];i;i=noww[i])
    45     {
    46         pp[nd]=i;
    47         if(dep[goal[i]]==dep[nd]+1)
    48             if(tep=Augmenting(goal[i],ed,min(mn,flow[i])))
    49             {
    50                 flow[i]-=tep,mn-=tep;
    51                 flow[i^1]+=tep,tmp+=tep;
    52                 if(!mn) break;
    53             }
    54     }
    55     return tmp;
    56 }
    57 void Dinic_Maxflow(int st,int ed)
    58 {
    59     while(Layering(st,ed))
    60         ans+=Augmenting(st,ed,inf);
    61 }
    62 int main ()
    63 {
    64     scanf("%d%d",&n,&m);
    65     cnt=1,num=n*m+2,tot=n*m,s=n*m+1,t=n*m+2;
    66     for(int i=1;i<=n;i++)
    67         for(int j=1;j<=m;j++)
    68         {
    69             scanf("%d",&rd);
    70             bro[i][j]=rd,tot-=rd;
    71         }
    72     for(int i=1;i<=n;i++)
    73         for(int j=1;j<=m;j++)
    74             if(!bro[i][j]) 
    75             {
    76                 if((i^j)&1)
    77                 {
    78                     link(s,tonum(i,j),1);
    79                     for(int k=0;k<8;k++)
    80                     {
    81                         t1=i+mov[k][0],t2=j+mov[k][1];
    82                         if(check(t1,t2)&&!bro[t1][t2]) 
    83                             link(tonum(i,j),tonum(t1,t2),1);
    84                     }
    85                 }
    86                 else link(tonum(i,j),t,1);
    87             }
    88     Dinic_Maxflow(s,t);
    89     printf("%d",tot-ans);
    90     return 0;
    91 }
    92 
    View Code
  • 相关阅读:
    机器学习常用算法
    判别式模型与生成式模型
    数据清洗方法
    机器学习项目流程清单
    免费的论文查重网站
    (转载)python应用svm算法过程
    opencv图像阈值设置的三种方法
    Tensorflow读取csv文件(转)
    tensorflow的数据输入
    为什么有些图像在显示前要除以255?(zhuan)
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10046737.html
Copyright © 2020-2023  润新知