博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【图论】[ZOJ1002]Fire Net
阅读量:5086 次
发布时间:2019-06-13

本文共 1675 字,大约阅读时间需要 5 分钟。

二分图匹配,建图方式巧妙,横向连通块(在一行,中间没有障碍物)、纵向连通块分别为x,y部,相交的连边,求最大匹配。

#include
#include
#define MAXN 4int n,a[MAXN+10][MAXN+10],cnt,cnt1,c[MAXN*MAXN*2+10],ans;char s[MAXN+2][MAXN+2];bool vis[MAXN*MAXN*2+10];struct node{ int v; node *next;}edge[MAXN*MAXN*MAXN*MAXN*2+10],*adj[MAXN*MAXN*2+10],*ecnt=edge;void addedge(int u,int v){ node *p=++ecnt; p->v=v; p->next=adj[u]; adj[u]=p;}bool dfs(int u){ int v; for(node *p=adj[u];p;p=p->next){ v=p->v; if(!vis[v]){ vis[v]=1; if(!c[v]||dfs(c[v])){ c[u]=v; c[v]=u; return 1; } } } return 0;}void maxmatch(){ for(int i=1;i<=cnt1;i++){ memset(vis,0,sizeof vis); if(!c[i]&&dfs(i)) ans++; }}int main(){ int i,j; while(scanf("%d",&n)){ if(!n) return 0; memset(c,0,sizeof c); memset(adj,0,sizeof adj); memset(a,0,sizeof a); ans=cnt=0; ecnt=edge; for(i=1;i<=n;i++) scanf("%s",s[i]+1); for(i=1;i<=n;i++) for(j=1;j<=n;j++){ if(s[i][j]!='.') continue; if(s[i][j-1]!='.') cnt++; a[i][j]=cnt; } cnt1=cnt; for(j=1;j<=n;j++) for(i=1;i<=n;i++){ if(s[i][j]!='.') continue; if(s[i-1][j]!='.') cnt++; addedge(a[i][j],cnt); addedge(cnt,a[i][j]); } maxmatch(); printf("%d\n",ans); }}

转载于:https://www.cnblogs.com/outerform/p/5921941.html

你可能感兴趣的文章
创龙TMS320C6748开发板串口和中断学习笔记
查看>>
01 C语言程序设计--01 C语言基础--第3章 基本数据类型01
查看>>
Java 反射机制详解(上)
查看>>
oracle drop table(表)数据恢复方法
查看>>
编译LAMP部署动态网站环境
查看>>
Java 8 新的时间日期 API
查看>>
PHP基本语法
查看>>
Linux命令应用大词典-第8章 日期和时间
查看>>
jenkins+maven+svn构建项目,及远程部署war包到tomcat上
查看>>
图解CSS3之弹性盒模型篇(display:box / display:inline-box)
查看>>
【iOS】UIImageView 点击事件
查看>>
自动跟踪足球场上所有的选手
查看>>
训练深度学习网络时候,出现Nan 或者 震荡
查看>>
Lintcode--010(最长上升子序列)
查看>>
机器学习(3):支持向量机(SVM)
查看>>
SQL技术内幕-13 SQL优化方法论之分离重量级的等待
查看>>
mysql--增删改查
查看>>
mysql--多表联合查询
查看>>
HDOJ 1233 还是畅通工程
查看>>
垃圾回收机制
查看>>