Attacking rooks |
Time Limit: 20000ms, Special Time Limit:50000ms, Memory Limit:65536KB |
Total submit users: 12, Accepted users: 7 |
Problem 13028 : No special judgement |
Problem description |
Chess inspired problems are a common source of exercises in algorithms classes. Starting with the well known 8-queens problem, several generalizations and variations were made. One of them is the N-rooks problem, which consists of placing N rooks in an N by N chessboard in such a way that they do not attack each other. Professor Anand presented the N-rooks problem to his students. Since rooks only attack each other when they share a row or column, they soon discovered that the problem can be easily solved by placing the rooks along a main diagonal of the board. So, the professor Given the size of the board and the location of the pawns, tell Professor Anand the maximum number of rooks that can be placed on empty squares such that no two of them attack each other. |
Input |
The first line contains an integer N (1 ≤ N ≤ 100) representing the number of rows and columns of the board. Each of the next N lines contains a string of N characters. In the i-th of these strings, the j-th character represents the square in the i-th row and j-th column of the board. The character is either "." (dot) or the uppercase letter "X", indicating respectively an empty square or a square containing a pawn. |
Output |
Output a line with an integer representing the maximum number of rooks that can be placed on the empty squares of the board without attacking each other. |
Sample Input |
Sample input 1 5 X.... X.... ..X.. .X... ....X Sample input 2 4 .... .X.. .... .... Sample input 3 1 X |
Sample Output |
Sample output 1 7 Sample output 2 5 Sample output 3 0 |
Problem Source |
ICPC Latin American Regional 2013
#include<stdio.h> #include<iostream> #include<string.h> #include<vector> using namespace std; vector<int>map[10005]; int match[10005],vist[10005]; int find(int x) { int len=map[x].size(); for(int i=0;i<len;i++) if(vist[map[x][i]]==0) { vist[map[x][i]]=1; if(match[map[x][i]]==0||find(match[map[x][i]])) { match[map[x][i]]=x; return 1; } } return 0; } int main() { int n,rn,ln,t=0,mpr[105][105],mpl[105][105]; char c; while(scanf("%d",&n)>0) { for(int i=1;i<=n;i++) { getchar(); for(int j=1;j<=n;j++) { mpr[i][j]=mpl[i][j]=0; scanf("%c",&c); if(c=='X') mpr[i][j]=mpl[i][j]=-1; } } rn=0; for(int i=1;i<=n;i++)//一行变多行 for(int j=1;j<=n;j++) { while(mpr[i][j]==-1&&j<=n)j++; rn++; while(mpr[i][j]!=-1&&j<=n) { mpr[i][j]=rn; j++; } } ln=0; for(int j=1;j<=n;j++)//一列变多列 for(int i=1;i<=n;i++) { while(mpl[i][j]==-1&&i<=n)i++; ln++; while(mpl[i][j]!=-1&&i<=n) { mpl[i][j]=ln; i++; } } for(int i=1;i<=rn;i++) map[i].clear(); for(int i=1;i<=n;i++)//行列建图 for(int j=1;j<=n;j++) if(mpr[i][j]!=-1) map[mpr[i][j]].push_back(mpl[i][j]); memset(match,0,sizeof(match)); int ans=0; for(int i=1;i<=rn;i++) { for(int j=0;j<=ln;j++) vist[j]=0; ans+=find(i); } printf("%d\n",ans); } } |
HNU13028Attacking rooks (二分匹配,一行变多行,一列变多列)
时间: 2024-10-03 03:53:40
HNU13028Attacking rooks (二分匹配,一行变多行,一列变多列)的相关文章
UVALive 6525 Attacking rooks 二分匹配 经典题
题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=4536">点击打开链接 题意: 给定n*n的棋盘, 能够在'.'上摆 象棋中的车(X是墙壁) 使得随意两个车都不能互相攻击到 问:最多能摆多少个车. 思路: 二分匹配 1.若没有X.那么做法就是 X点集为行,Y点集为列,对于图上的每一个点所在的行和列(x,y) 建一条边 x->y 2.有了X,那么对于每一个点所在的上方能接触到的X必须
LA 6525 Attacking rooks 二分匹配
题意: 给定n*n的棋盘, 可以在'.'上摆 象棋中的车(X是墙壁) 使得任意两个车都不能互相攻击到 求最多能摆多少个车. 思路:将每行中连续为.的作为X集合中一个点,同样,将每列中连续为.的点作为Y集合中的一个点.对原图中每个'.',将其对应的X 集合和Y集合中的标号建边,便形成了二分图,对该图求最大匹配.详见代码: /********************************************************* file name: LA6525.cpp author :
hdu1045Fire Net (一行变多行,一列变多列,最小顶点覆盖)
Fire Net Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6280 Accepted Submission(s): 3549 Problem Description Suppose that we have a square city with straight streets. A map of a city is a square
ASP.NET_正则表达式_匹配HTML中的一行或多行
一.匹配数字串/flash/([0-9]+).htm二.匹配不含双引号的字符串<p class=\"w490\">([^\"]+)</p>三.匹配一行cnt\">(.+)\n四.匹配多行的"divAll\">([\\s\\S]*)<div id=PS:牧工 懒惰"divAll\">([\\s\\S]*?)<div id=\"divFooter"
一行多列变多行多列  ;
问题: aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp拆分为:aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp 解答: xargs -n4 awk -vRS=' ' 'ORS=NR%4?" ":"\n"' sed 's/ /\n/4;P;D' 一行多列变多行多列
Hdu 1045 二分匹配
题目链接 Fire Net Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6282 Accepted Submission(s): 3551 Problem Description Suppose that we have a square city with straight streets. A map of a city i
二分匹配的常用建图方法
学习了一些常用建图方法,又理解了一遍二分,感觉更加清晰了. 1.行列匹配法:在一个矩阵中,加入上面一些点有人,现在有一些箭能将一行或一列的人杀死,问最少需要多少箭?因为箭要最少,所以要尽可能的在一行或一列上,即最小顶点覆盖问题.这时可以通过行列来进行二分匹配:假如位置(1,1),(1,3),(2,2),(3,1) 则横坐标1 2 3,纵坐标 1 2 3间有一定的关系,最小点覆盖=最大匹配数: 2.反建法:假如有一个嫉妒封建的老师,他不希望同学间发生恋情.老师发现,满足一下条件的同学发生恋情的几率
LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配
#2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 小凸和小方是好朋友,小方给小凸一个 N×M N \times MN×M(N≤M N \leq MN≤M)的矩阵 A AA,要求小凸从其中选出 N NN 个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的 N NN 个数中第 K KK 大的数字的最小值是多少. 输入格式 第一行给出三个整数
poj 2226 Muddy Fields(合理建图+二分匹配)
1 /* 2 题意:用木板盖住泥泞的地方,不能盖住草.木板任意长!可以重叠覆盖! '*'表示泥泞的地方,'.'表示草! 3 思路: 4 首先让我们回忆一下HDU 2119 Matrix这一道题,一个矩阵中只有0, 1,然后让我们通过选择一行,或者 5 是一列将其所在行的或者所在列的 1全部删掉,求出最少需要几步? 6 7 这道题的思路就是:将行标 和 列标值为1的建立一条边!通过匈牙利算法可以得到这个二分图的最大匹配数 8 最大匹配数==最小顶点覆盖数!最小顶点覆盖就是用最少的点覆盖了这个二分图