专栏文章
题解
P7668题解参与者 6已保存评论 5
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @miqoyr5i
- 此快照首次捕获于
- 2025/12/04 08:22 3 个月前
- 此快照最后确认于
- 2025/12/04 08:22 3 个月前
模拟赛 T1,网络流碾过去了,感觉很容易被卡。
将行和列分开处理,则会有一些互相冲突的
RGW。考虑把横竖冲突的
CPPRGW 连边,则发现这是一个二分图,二分图的最大匹配即把冲突都解决了,网络流求最小割即可。#include<bits/stdc++.h>
using namespace std;
const int N=9e6+10,M=9e6+10,inf=0x3f3f3f3f,s=0;
int n,m,t,cnt,tot=1,ans,head[N],now[N],dis[N],use[3010][3010];char S[3010][3010];
struct edge{int to,nxt,w;}e[M<<1];
inline void add(int u,int v,int w){e[++tot]={v,head[u],w},head[u]=tot;}
inline void Add(int u,int v,int w){add(u,v,w),add(v,u,0);}
inline bool bfs(int s,int t){
queue<int>q;for(int i=0;i<=cnt;i++)dis[i]=inf;
q.push(s),dis[s]=0,now[s]=head[s];
while(!q.empty()){
int x=q.front();q.pop();
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].to;
if(e[i].w&&dis[y]==inf){
q.push(y),dis[y]=dis[x]+1,now[y]=head[y];
if(y==t)return 1;
}
}
}return 0;
}int dfs(int x,int sum){
if(x==t)return sum;
int k,ret=0;
for(int i=now[x];i&∑i=e[i].nxt){
now[x]=i;int y=e[i].to;
if(e[i].w&&dis[y]==dis[x]+1){
k=dfs(y,min(sum,e[i].w));
if(!k)dis[y]=inf;
e[i].w-=k,e[i^1].w+=k,sum-=k,ret+=k;
}
}return ret;
}void dinic(){while(bfs(s,t))ans+=dfs(s,inf);}
int main(){
ios::sync_with_stdio(cin.tie(cout.tie()));
cin>>n>>m;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>S[i][j];
for(int i=1;i<=n-2;i++)for(int j=1;j<=m;j++)if(S[i][j]=='R'&&S[i+1][j]=='G'&&S[i+2][j]=='W')Add(s,++cnt,1),use[i][j]=use[i+1][j]=use[i+2][j]=cnt;
int tmp=cnt+1;
for(int i=1;i<=n;i++)for(int j=1;j<=m-2;j++)if(S[i][j]=='R'&&S[i][j+1]=='G'&&S[i][j+2]=='W'){
++cnt;
if(use[i][j])Add(use[i][j],cnt,1);
if(use[i][j+1])Add(use[i][j+1],cnt,1);
if(use[i][j+2])Add(use[i][j+2],cnt,1);
}t=++cnt;
for(int i=tmp;i<cnt;i++)Add(i,t,1);
return dinic(),cout<<cnt-1-ans,0;
}
相关推荐
评论
共 5 条评论,欢迎与作者交流。
正在加载评论...