模拟战役
思路分析:
就是求出2个阵营的连通块的个数 如果 司机更大的话 就-1
else sort连通块的连通个数除去n1个最小的 剩下的和就是ans
思路1: 并查集实现
思路2:dfs搜索
/*
*@Author: GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
* __----~~~~~~~~~~~------___
* . . ~~//====...... __--~ ~~
* -. \_|// |||\\ ~~~~~~::::... /~
* ___-==_ _-~o~ \/ ||| \\ _/~~-
* __---~~~.==~||\=_ -_--~/_-~|- |\\ \\ _/~
* _-~~ .=~ | \\-_ '-~7 /- / || \ /
* .~ .~ | \\ -_ / /- / || \ /
* / ____ / | \\ ~-_/ /|- _/ .|| \ /
* |~~ ~~|--~~~~--_ \ ~==-/ | \~--===~~ .\
* ' ~-| /| |-~\~~ __--~~
* |-~~-_/ | | ~\_ _-~ /\
* / \ \__ \/~ \__
* _--~ _/ | .-~~____--~-/ ~~==.
* ((->/~ '.|||' -_| ~~-/ , . _||
* -_ ~\ ~~---l__i__i__i--~~_/
* _-~-__ ~) \--______________--~~
* //.-~~~-~_--~- |-------~~~~~~~~
* //.-~~~--\
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 神兽保佑 永无BUG
*/
const int MAX=10010;
char a[110][110];
int num[MAX];
int fa[MAX];
int find(int x){
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
void add(int x,int y){
int xx=find(x);
int yy=find(y);
if(xx!=yy){
fa[xx]=yy;
num[yy]+=num[xx];
}
}
int main(){
int n;
cin>>n;
for(int i=1;i<=8;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
fa[j+n*(i-1)]=j+n*(i-1);
num[j+n*(i-1)]=1;
}
}
for(int i=1;i<=8;i++){
for(int j=1;j<=n;j++){
if(a[i][j]=='*'){
for(int k=0;k<8;k++){
int x=i+xd[k];
int y=j+yd[k];
if(y<=n&&(x<=4&&i<=4)||(x>4&&i>4&&x<=8)){
if(a[x][y]=='*'){
add(y+n*(x-1),j+n*(i-1));
}
}
}
}
}
}
int n1=0;
int n2=0;
int v[MAX];
for(int i=1;i<=8;i++){
for(int j=1;j<=n;j++){
if(a[i][j]=='*'&&fa[j+n*(i-1)]==j+n*(i-1)){
if(i<=4){
n1++;
}
else {
v[n2++]=num[j+n*(i-1)];
}
}
}
}
// cout<<n1<<" "<<n2;
sort(v,v+n2);
if(n1>n2) cout<<-1<<endl;
else {
int ans=0;
for(int i=n1-1;i<n2;i++)
ans+=v[i];
cout<<ans<<endl;
}
}