kuangbin专题十 HDU1045(二分图orDFS)
2018-01-11 14:55
169 查看
题意:
给你一幅图,‘#’代表墙,’.’表示可以行走,现在要在’.’上放置大炮,放置了大炮的这些点的上下左右不能再放其他大炮,除非有墙隔着,问最多可以放多少个这样的点。
题解:
这道题可以用DFS和二分图来做,DFS。。感觉自己像个智障一样,简单的DFS都写不出来,明明BFS那么熟练了。。为什么一到DFS像个傻子呢,哎。这道题的DFS类似于八皇后问题,额。。还是来说一下二分图吧。
二分图怎么弄呢?就是将行和列看作点,那么如果行和列的关系为‘.’的话就说明之间有联系,然后就上匈牙利算法就可以过了,难就难在怎么缩点建图了。弄两个block二维数组,分别对应行和列,然后如何没有‘#’就代表属于一个点的,就可以了,具体操作看我代码。
二分图:
DFS:
给你一幅图,‘#’代表墙,’.’表示可以行走,现在要在’.’上放置大炮,放置了大炮的这些点的上下左右不能再放其他大炮,除非有墙隔着,问最多可以放多少个这样的点。
题解:
这道题可以用DFS和二分图来做,DFS。。感觉自己像个智障一样,简单的DFS都写不出来,明明BFS那么熟练了。。为什么一到DFS像个傻子呢,哎。这道题的DFS类似于八皇后问题,额。。还是来说一下二分图吧。
二分图怎么弄呢?就是将行和列看作点,那么如果行和列的关系为‘.’的话就说明之间有联系,然后就上匈牙利算法就可以过了,难就难在怎么缩点建图了。弄两个block二维数组,分别对应行和列,然后如何没有‘#’就代表属于一个点的,就可以了,具体操作看我代码。
二分图:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN=50; char s[MAXN][MAXN]; bool vis[MAXN]; bool map[MAXN][MAXN]; int block1[MAXN][MAXN],block2[MAXN][MAXN]; int cx[MAXN],cy[MAXN]; int n,x1,y1; void build() { x1=1,y1=1; for(int i=0;i<n;i++)//行 { for(int j=0;j<n;j++) if(s[i][j]=='X') x1++; else block1[i][j]=x1; x1++;//这里可能会出现最后一列有个#导致x1++,而这里也x1++,导致x1多了1,但是没影响,因为多出来的这个数没有其他数与他搭建关系,要的是缩点的关系。 } // printf("x1 =%d\n",x1); for(int j=0;j<n;j++)//列 { for(int i=0;i<n;i++) if(s[i][j]=='X') y1++; else block2[i][j]=y1; y1++; } for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(s[i][j]=='.') map[block1[i][j]][block2[i][j]]=true; } int dfs(int u) { for(int v=1;v<y1;v++) { if(map[u][v]&&!vis[v]) { vis[v]=true; if(cy[v]==-1||dfs(cy[v])) { cx[u]=v; cy[v]=u; return 1; } } } return 0; } int main() { while(~scanf("%d",&n),n) { memset(map,false,sizeof(map)); memset(cx,-1,sizeof(cx)); memset(cy,-1,sizeof(cy)); memset(block1,0,sizeof(block1)); memset(block2,0,sizeof(block2)); for(int i=0;i<n;i++) scanf("%s",&s[i]); build(); int ans=0; for(int i=1;i<x1;i++) { memset(vis,false,sizeof(vis)); ans+=dfs(i); } printf("%d\n",ans); } }
DFS:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN=15; char s[MAXN][MAXN]; bool map[MAXN][MAXN]; int n,ans; bool flag; bool check(int x,int y) { if(s[x][y]=='X'||map[x][y]) return false; for(int i=x;i>=0;i--){ if(map[i][y]) return false; if(s[i][y]=='X') break; } for(int i=x;i<n;i++){ if(map[i][y]) return false; if(s[i][y]=='X') break; } for(int i=y;i>=0;i--){ if(map[x][i]) return false; if(s[x][i]=='X') break; } for(int i=y;i<n;i++){ if(map[x][i]) return false; if(s[x][i]=='X') break; } return true; } void dfs(int x,int num) { if(num>ans) ans=num; // printf("%d %d %d\n",x,num,ans); if(x==n*n) return ; int x1=x/n; int y1=x%n; if(check(x1,y1)) { map[x1][y1]=true; dfs(x+1,num+1); map[x1][y1]=false; } dfs(x+1,num); } int main() { while(~scanf("%d",&n)) { if(n==0) break; ans=0; memset(map,false,sizeof(map)); for(int i=0;i<n;i++) scanf("%s",s[i]); dfs(0,0); printf("%d\n",ans); } }
相关文章推荐
- [kuangbin带你飞]专题十 匹配问题 (二分图最大匹配)(二分图染色)(模板)
- [kuangbin带你飞]专题十 匹配问题 二分图多重匹配
- [kuangbin带你飞]专题十 匹配问题 二分图最大权匹配
- kuangbin专题十 HDU3829 二分图+最大独立集
- [kuangbin带你飞]专题十 匹配问题 L - Cat VS Dog (二分图最大独立集)
- kuangbin专题十 HDU2444 二分图判断+匈牙利算法
- [kuangbin带你飞]专题十一 网络流 A POJ - 3436
- [kuangbin带你飞]专题一 简单搜索H - Pots(POJ 3414)
- [kuangbin带你飞]专题一 简单搜索 N
- [kuangbin带你飞]专题四 最短路练习 B
- kuangbin专题K(next数组)
- [kuangbin带你飞]专题十一 网络流
- [kuangbin带你飞]专题一 简单搜索 - B - Dungeon Master
- [kuangbin带你飞]专题一 简单搜索 -I - Fire Game
- [kuangbin带你飞]专题一 简单搜索 -G - Shuffle'm Up
- [kuangbin带你飞]专题十八 后缀数组
- kuangbin专题一B题:POJ2251:Dungeon Master
- [kuangbin带你飞]专题二 搜索进阶 题解(康托展开、映射、迭代加深)
- kuangbin专题五: D - How Many Answers Are Wrong HDU - 3038 (带权并查集)
- kuangbin专题五 并查集 POJ2236-Wireless Network