当前位置: 首页 > 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.gsyq.cn/news/1329.html

相关文章:

  • Vue 将api 获取的 json 数据保存到本地
  • Claude Code新手入门指南:AI编程助手完全教程
  • cmov用法一例
  • Codeforces Round 1049 (Div. 2)(A~D)
  • Python基础-27 match-case 使用教程
  • 准备工作之结构体[基于郝斌课程]
  • 软工课程第一次作业
  • 初始化树莓派(Raspberry Pi)系统并以 ssh 连接教程(只需读卡器、手机开热点,无需显示器) - tsunchi
  • CF
  • Ubuntu 安装 VSCode
  • A
  • 【2024-2025第二学期】助教工作学期总结
  • 对抗样本
  • ssh相关问题
  • 使用 Visual Studio 2022 创建动态库和静态库 - Invinc
  • 软件
  • 打工人必看!昆工MBA“项目管理”杀疯了
  • 201912_BUUCTF_Base64隐写
  • 软考达人-案例分析
  • kettle插件-sqlserver cdc插件,从sqlserver获取实时数据so easy,早早下班
  • try hack me.md
  • 7. LangChain4j + 记忆缓存详细说明 - Rainbow
  • 在AI技术唾手可得的时代,挖掘新需求成为制胜关键——某知名语音识别框架需求洞察
  • 英语_阅读_raise awareness about water conservation_待读
  • [豪の学习笔记] 软考中级备考 基础复习#5
  • 02020212 .NET Core重难点知识12-服务定位器、.NET依赖注入示例
  • apache详细配置
  • 9.8总结
  • 在 AlmaLinux 9 使用 Podman 部署 Redis 7.4.5 并优化内核参数
  • 基于调度场算法将中缀表达式转换为后缀表达式