题解:
不能通过第二种方法从
0
0
0 变成
1
1
1 的需要多花费
1
1
1,只需要计算有最少有多少个第一种情况。考虑把每一行每一列看成一个独立的点共
(
N
+
M
)
(N+M)
(N+M) 个点,考虑点
(
x
,
y
)
(x,y)
(x,y) 是
1
1
1 ,则把对应的行
i
i
i 和列
j
j
j 连接。那么可以看出,在同一个连通块内的边都可以通过情况
2
2
2 得到。所以问题可以转化为连通块个数。
code:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int cnt0;// 0的数量
int cnt;// 连通块的数量
string s[1010];
vector<int> adj[2010];
int v[2010];// 标记哪个点属于哪个
void dfs(int x)
{
v[x] = 1;
for(int y : adj[x])
{
if(v[y]) continue;
dfs(y);
}
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i++)
{
cin >> s[i];
for(int j = 0; j < m; j++)
if(s[i][j] == '1')
{
adj[i].push_back(j + n);
adj[j + n].push_back(i);
}
else
cnt0++;
}
int res = 3 * cnt0;
for(int i = 0; i < n + m; i++)
{
if(!v[i])
{
cnt++;
dfs(i);
}
}
cout << res + cnt - 1;
return 0;
}