【题解】[CQOI2017] 老C的方块

题目描述

在这里插入图片描述
在这里插入图片描述

sol:

其实是最小割的板题。

首先看到网格图,以及这个奇怪的形状,我们想到网络流。

为了赋予它实际意义,我们考虑染色。

这样就转化成了一条 1-2-3-4 的路径。

最后按照割点的方式做即可。

总结:本题虽然思维难度不大,但是建图方式是非常常见的,与 文理分科 不同,那道题有 选文 /理科 两种状况和对应贡献,所以要文边建左边,理边建右边;本题直接用分层图的思想来建就好了。

qwq

#include<bits/stdc++.h> #define ll long long #define INF 0x3f3f3f3f using namespace std; const int N=2e5+5; const int M=1e7+5; int r,c,n,s,t,rt,res,id[2][N]; int lab[N],que[N],cur[N]; int tot,head[M],nxt[M],to[M],cap[M]; int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1}; int col[4][4]={{2,1,2,1},{3,4,3,4},{4,3,4,3},{1,2,1,2}}; map<pair<int,int>,int> xf; struct node{ int x,y,z,col; }a[N]; void add(int u,int v,int w) { tot++; nxt[tot]=head[u],head[u]=tot,to[tot]=v,cap[tot]=w; } inline int read() { int x=0,f=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=(x<<1)+(x<<3)+c-'0'; c=getchar(); } return x*f; } bool BFS() { for(int i=0;i<=rt;i++) lab[i]=0; lab[t]=1; int qhead=0,qtail=0; que[qtail++]=t; while(qhead!=qtail) { int u=que[qhead++]; for(int k=head[u];k;k=nxt[k]) { int v=to[k]; if(cap[k^1]==0||lab[v]>0) { continue; } lab[v]=lab[u]+1; que[qtail++]=v; } } return lab[s]!=0; } int flow(int u,int limit) { if(u==t) { return limit; } int used=0; for(int k=cur[u];k;k=nxt[k]) { int v=to[k]; cur[u]=k; if(lab[u]!=lab[v]+1||cap[k]==0) { continue; } int tmp=min(limit-used,cap[k]); int ret=flow(v,tmp); used+=ret; cap[k]-=ret; cap[k^1]+=ret; if(ret==0||cap[k]==0) { cur[u]=nxt[k]; } if(limit==used) break; } return used; } int calc(int x,int y) { return col[(x-1)%4][(y-1)%4]; } bool outside(int x,int y) { if(x<1||x>r||y<1||y>c) return 1; return 0; } int dinic() { int tot=0; while(BFS()) { for(int i=0;i<=rt;i++) cur[i]=head[i]; tot+=flow(s,INF); } return tot; } int main() { tot=1; for(int i=0;i<=rt;i++) { head[i]=0; } s=rt=0; r=read(),c=read(),n=read(); for(int i=1;i<=n;i++) { a[i].x=read(),a[i].y=read(),a[i].z=read(),a[i].col=calc(a[i].x,a[i].y); xf[make_pair(a[i].x,a[i].y)]=i; for(int j=0;j<2;j++) { id[j][i]=++rt; } res+=a[i].z; } t=++rt; for(int i=1;i<=n;i++) { int col=calc(a[i].x,a[i].y); add(id[0][i],id[1][i],a[i].z); add(id[1][i],id[0][i],0); if(col==1) { add(s,id[0][i],INF); add(id[0][i],s,0); } if(col==4) { add(id[1][i],t,INF); add(t,id[1][i],0); } for(int k=0;k<4;k++) { int ti=a[i].x+dx[k],tj=a[i].y+dy[k]; if(outside(ti,tj)) continue; if(xf.find(make_pair(ti,tj))==xf.end()) { continue; } int j=xf[make_pair(ti,tj)],col2=calc(ti,tj); if(col+1==col2) { add(id[1][i],id[0][j],INF); add(id[0][j],id[1][i],0); } } } printf("%d",dinic()); }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530210.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示