题意:给出一个矩阵表示的无向图,可以增边和删边使得任意子图中,任意点之间都连有一条边,最多增删10次,输出最小次数
分析:运用了floyd和点覆盖集的思想,对于一条已经连好的边,找到一个点和这条边的一个点有连边而和另一个点没有连边,修改这三个点的连边情况,dfs即可
代码:
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define FRER() freopen("i.txt","r",stdin);
#define FREW() freopen("o.txt","w",stdout);
using namespace std;
typedef long long ll;
const int maxn = 100 + 7;
int G[maxn][maxn];
int n,res;
void scan_d(int &ret){
char c;
ret = 0;
while((c=getchar())<'0'||c>'9');
while(c>='0'&&c<='9'){
ret = ret*10 + (c-'0'), c= getchar();
}
}
void dfs(int d){
// cout<<d<<endl;
if(d>=res)return;
int a,b,c;
a = b = c = 0;
for(int i=1;i<=n&&!a;i++){
for(int j=i+1;j<=n&&!a;j++){
if(G[i][j]){
for(int k=1;k<=n&&!a;k++){
if(i!=k&&j!=k&&(G[i][k]^G[k][j])){
a = i;
b = j;
c = k;
}
}
}
}
}
if(!a){
res = d;
return;
}
G[a][b] = G[b][a] = G[a][b]^1;
dfs(d+1);
G[a][b] = G[b][a] = G[a][b]^1;
G[a][c] = G[c][a] = G[a][c]^1;
dfs(d+1);
G[a][c] = G[c][a] = G[a][c]^1;
G[b][c] = G[c][b] = G[b][c]^1;
dfs(d+1);
G[b][c] = G[c][b] = G[b][c]^1;
}
int main(){
//freopen("i.txt","r",stdin);
int T,k=1;
scan_d(T);
while(T--){
scan_d(n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scan_d(G[i][j]);
res = 11;
dfs(0);
printf("Case #%d: %d\n",k++,res==11?-1:res);
}
return 0;
}