题目描述


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__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」