看起来很像网络流的二分图套路题,然后我们大力观察(题目定义的相邻我用引号括起来,应该能看懂)
发现“相邻”的一对方格如果各自连着一个一个方格就gg了,于是对于所有这些“相邻”的方格,我们有两种选择
①移除一对“相邻”的方格中的一个
②把一对“相邻”的方格中的一个的所有相邻方格都移除
还可以发现二分图染色后一对“相邻”方格相邻的方格是一边白一边黑的
那么对于一对“相邻”的点连流量为点权最小值的边,黑白点分开向源汇点连流量等于点权的边,最后“相邻”点和和它们相邻的点用流量为正无穷的边连起来,然后图就建好了
1 #include<map> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int N=100005,M=400005,inf=1e9; 8 const int mov[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; 9 int p[N],pp[N],noww[2*M],goal[2*M],flow[2*M]; 10 int dep[N],que[N],px[N],py[N],col[N],val[N]; 11 int n,c,r,s,t,f,b,t1,t2,t3,cnt,tot,ans; 12 map<pair<int,int>,int> mmp; 13 void link(int f,int t,int v) 14 { 15 noww[++cnt]=p[f],p[f]=cnt; 16 goal[cnt]=t,flow[cnt]=v; 17 noww[++cnt]=p[t],p[t]=cnt; 18 goal[cnt]=f,flow[cnt]=0; 19 } 20 bool Layering(int st,int ed) 21 { 22 for(int i=1;i<=t;i++) pp[i]=p[i]; 23 memset(dep,-1,sizeof dep); 24 dep[st]=0,que[f=b=0]=st; 25 while(f<=b) 26 { 27 int tn=que[f++]; 28 for(int i=pp[tn];i;i=noww[i]) 29 if(dep[goal[i]]==-1&&flow[i]) 30 dep[goal[i]]=dep[tn]+1,que[++b]=goal[i]; 31 } 32 return ~dep[ed]; 33 } 34 int Augmenting(int nd,int ed,int mn) 35 { 36 if(nd==ed||!mn) return mn; 37 int tmp=0,tep=0; 38 for(int i=pp[nd];i;i=noww[i]) 39 { 40 pp[nd]=i; 41 if(dep[goal[i]]==dep[nd]+1) 42 if(tep=Augmenting(goal[i],ed,min(mn,flow[i]))) 43 { 44 flow[i]-=tep,mn-=tep; 45 flow[i^1]+=tep,tmp+=tep; 46 if(!mn) break; 47 } 48 } 49 return tmp; 50 } 51 void Dinic_Maxflow(int st,int ed) 52 { 53 while(Layering(st,ed)) 54 ans+=Augmenting(st,ed,inf); 55 } 56 int main () 57 { 58 scanf("%d%d%d",&c,&r,&n),cnt=1; 59 for(int i=1;i<=n;i++) 60 { 61 scanf("%d%d%d",&px[i],&py[i],&val[i]); 62 mmp[make_pair(px[i],py[i])]=++tot; 63 } 64 s=++tot,t=++tot; 65 for(int i=1;i<=n;i++) 66 { 67 int f=px[i]%4,g=py[i]%2; 68 if(!f) col[i]=g?3:1; 69 else if(f==1) col[i]=g?1:3; 70 else if(f==2) col[i]=g?2:4; 71 else if(f==3) col[i]=g?4:2; 72 } 73 for(int i=1;i<=n;i++) 74 if(col[i]==1) 75 for(int j=0;j<4;j++) 76 { 77 int tx=px[i]+mov[j][0],ty=py[i]+mov[j][1],num=mmp[make_pair(tx,ty)]; 78 if(num) (col[num]==2)?link(i,num,min(val[i],val[num])):link(num,i,inf); 79 } 80 else if(col[i]==2) 81 for(int j=0;j<4;j++) 82 { 83 int tx=px[i]+mov[j][0],ty=py[i]+mov[j][1],num=mmp[make_pair(tx,ty)]; 84 if(num&&col[num]!=1) link(i,num,inf); 85 } 86 else if(col[i]==3) link(s,i,val[i]); 87 else if(col[i]==4) link(i,t,val[i]); 88 Dinic_Maxflow(s,t),printf("%d",ans); 89 return 0; 90 }