1. 程式人生 > >解題:BZOJ4808 馬

解題:BZOJ4808 馬

網絡流 匹配 flow 網絡 while ini memset div blank

題面

以前寫過的題,翻出來學習網絡流寫二分圖匹配,因為復雜度更優秀,$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

解題:BZOJ4808 馬