象棋
描述
你有足够多的象棋“车”,在一个n×n的棋盘上你能放多少个“车”呢?注意,所给棋盘上有些位置不能放任何东西。同时,某一行(列)最多只能存在一个“车”。
输入
第一行为一个正整数n。
接下来n行,每行包含n个整数,若为0表示这个位置不能放“车”;若为1表示这个位置可以放“车”。
输出
输出一个整数,表示最多能放多少个“车”。
样例1输入
5
1 0 0 0 0
0 0 0 0 0
0 0 0 1 0
1 1 0 1 0
0 0 0 1 0
样例1输出
3
样例1解释
我们这样放就只能放2个“车”:
车 0 0 0 0
0 0 0 0 0
0 0 0 1 0
1 0 0 车 0
0 0 0 1 0
若我们这样放就能放下3个了:
车 0 0 0 0
0 0 0 0 0
0 0 0 1 0
1 车 0 1 0
0 0 0 车 0
样例2
请查看下发文件内的sample2_input.txt和sample2_output.txt。
限制
对于30%的数据,n ≤ 5;
对于60%的数据,n ≤ 20;
对于100%的数据,n ≤ 500。
时间:2 sec
空间:256 MB
#include <bits/stdc++.h>
using namespace std;
// ================= 代码实现开始 =================
const int N = 505*2, M=N*N;
struct E{
int next,to;
}e[M];
int cnt ,ihead[N], mc[N];
bool vis[N];
void add(int x,int y){
++cnt;
e[cnt].next=ihead[x];
e[cnt].to=y;
ihead[x]= cnt;}
bool dfs(int x){
for(int i = ihead[x];i;i=e[i].next){
int y = e[i].to;
if(!vis[y]){
vis[y]=true;
if(mc[y]==0||dfs(mc[y])){
mc[x]=y;
mc[y]=x;
return true;
}
}
}return false;}
/* 请在这里定义你需要的全局变量 */
// 求解棋盘上最多能放多少个“车”
// n:棋盘的大小为n×n的
// board:所给棋盘,对于某个位置上的数:若值为1表示可以放“车”;若值为0表示不能放“车”
// 返回值:能放“车”的最大个数
int getAnswer(int n, vector<vector<int> > board) {
/* 请在这里设计你的算法 */
for(int i = 1;i<=n;++i)
for(int j = 1;j<=n;++j)
if(board[i-1][j-1]==1) add(i,j+n);
int ans = 0;
for(int i = 1;i<=n;++i)
if(!mc[i]){
memset(vis,0,sizeof(bool)*(2*n+1));
if(dfs(i))
++ans;
}
return ans;
}
// ================= 代码实现结束 =================
int main() {
int n;
scanf("%d", &n);
vector<vector<int> > e;
for (int i = 0; i < n; ++i) {
vector<int> t;
for (int j = 0; j < n; ++j) {
int x;
scanf("%d", &x);
t.push_back(x);
}
e.push_back(t);
}
printf("%d\n", getAnswer(n, e));
return 0;
}