当前位置: 首页 > news >正文

qoj6279 Honeycomb

题意

给出一个 \(n\times m\) 个六边形的网格,字符画形式给出,每两个格子之间可能有墙或无墙,问对每对不同的点来说使它们不连通增加的墙数量之和为多少。

\(n,m\le 100\),六边不全为墙的格子数量 \(\le 3000\)

思路

最大的一坨。

对每对不同的点求最小割,显然最小割树,直接模拟建图即可。

又因最大答案不超过 \(6\),所以跑网络流不会超时。

注意不要用 ISAP,会死的很惨。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
namespace mf{const int N=3010,INF=0x3f3f3f3f;struct node{int ed,w,id;};vector<node>e[N];int n,S,T;int dep[N],now[N];void init(int nn){for(int i=1;i<=nn;i++)e[i].clear();n=nn;}bool bfs(){memset(dep,-1,sizeof(dep));queue<int>q;q.push(S);dep[S]=0;while(!q.empty()){int t=q.front();q.pop();for (int i=0;i<e[t].size();i++){int ed=e[t][i].ed;if (dep[ed]==-1&&e[t][i].w){dep[ed]=dep[t]+1;q.push(ed);}}}memset(now,0,sizeof(now));return dep[T]!=-1;}int dfs(int st, int lim){if(st==T)return lim;for(int i=now[st];i<e[st].size();i++){now[st]=i;int ed=e[st][i].ed;if(dep[ed]==dep[st]+1&&e[st][i].w){int tmp=dfs(ed,min(e[st][i].w,lim));if(tmp){e[st][i].w-=tmp;e[ed][e[st][i].id].w+=tmp;return tmp;}}}return 0;}int dinic(){int r=0,flow;while(bfs())while(flow=dfs(S,INF))r+=flow;return r;}void add(int st,int ed,int w){int sti=e[st].size();int edi=e[ed].size();e[st].push_back({ed,w,edi});e[ed].push_back({st,0,sti});}
}
namespace go{struct node{int x,y,w;};vector<node> yt,t[3005];void add(int x,int y,int v){yt.push_back({x,y,v});}int n,a[3005],tmp[3005],dep[3005],f[3005],ans;bool can[3005];void build(int l,int r){if(l>=r) return;mf::init(n);int x=a[l],y=a[r];mf::S=x,mf::T=y;for(node v:yt)mf::add(v.x,v.y,v.w),mf::add(v.y,v.x,v.w);int w=mf::dinic();t[x].push_back({y,w});t[y].push_back({x,w});int tl=l-1,tr=r+1;for(int i=l;i<=r;i++){if(mf::dep[a[i]]!=-1) tmp[++tl]=a[i];else tmp[--tr]=a[i];}for(int i=l;i<=r;i++)a[i]=tmp[i];build(l,tl);build(tr,r);}void dfs(int x,int fa){if(f[x]!=0x3f3f3f3f) ans+=f[x];for(node v:t[x])if(v.x!=fa)f[v.x]=min(f[x],v.y),dfs(v.x,x);}
}
int T,n,m,id[1005][1005],tot;
string s[3005];
signed main(){cin>>T;for(int I=1;I<=T;I++){tot=0;go::yt.clear();go::ans=0;cin>>n>>m;cin.ignore();for(int i=1;i<=4*n+3;i++){getline(cin,s[i]);}for(int i=1;i<=4*n+3;i++){for(int j=0;j<s[i].length();j++){if(s[i][j]=='*') id[i][j]=++tot;}}for(int i=2;i<=4*n+3;i++){for(int j=1;j<s[i].length();j++){if(s[i-1][j-1]=='+'&&s[i+1][j+1]=='+'&&s[i][j]==' '){go::add(id[i+1][j-3],id[i-1][j+3],1);}if(s[i+1][j-1]=='+'&&s[i-1][j+1]=='+'&&s[i][j]==' '){go::add(id[i-1][j-3],id[i+1][j+3],1);}if(j>1&&j<s[i].length()-2&&s[i][j-2]=='+'&&s[i][j+2]=='+'&&s[i][j]==' '){go::add(id[i-2][j],id[i+2][j],1);}}}for(int i=1;i<=tot;i++)go::t[i].clear();go::n=tot;for(int i=1;i<=tot;i++)go::a[i]=i;go::build(1,tot);for(int i=1;i<=tot;i++)go::f[i]=0x3f3f3f3f,go::dfs(i,0);cout<<"Case #"<<I<<": "<<go::ans/2<<endl;}return 0;
}
http://www.hskmm.com/?act=detail&tid=495

相关文章:

  • Vue 将api 获取的 json 数据保存到本地
  • Claude Code新手入门指南:AI编程助手完全教程
  • 0124_观察者模式(Observer)
  • 读人形机器人07零售行业
  • 你可能不需要WebSocket-服务器发送事件的简单力量
  • 2014年11月微软安全更新风险评估与技术解析
  • 洛谷P5854 【模板】笛卡尔树 题解 笛卡尔树模板题
  • [Flink] Flink 经典场景:数据流输出到多个Sink
  • 都江堰操作系统
  • [OLAP/Doris] Doris 之表设计
  • cmov用法一例
  • 20250909 之所思 - 人生如梦
  • 认识人工智能-基础认知
  • Codeforces Round 1049 (Div. 2)(A~D)
  • 苹果im虚拟机协议群发系统,苹果imessage推信软件,苹果iMessage自动群发协议–持续更新中...
  • 【ChipIntelli 系列】SDK详解4——Makefile 设置 单SDK多工程文件夹实现方法
  • Codeforces Round 1049 (Div. 2)
  • 课前问题思考1
  • huggingface
  • 安全不是一个功能-而是一个地基
  • Python基础-27 match-case 使用教程
  • 从0到1实现Transformer模型-CS336作业1
  • 准备工作之结构体[基于郝斌课程]
  • 软工课程第一次作业
  • java学习起航喽
  • 初始化树莓派(Raspberry Pi)系统并以 ssh 连接教程(只需读卡器、手机开热点,无需显示器) - tsunchi
  • 从windows 自动进入BIOS
  • 软件工程第一次作业
  • Morpheus 审计报告分享:AAVE 项目 Pool 合约地址更新导致的组合性风险
  • Offer发放革命:Moka软件如何将平均入职转化率提升25%