给你一个图,你可以执行删边或者加边这样的操作,然后将这个图变成若干个团,问最小的步数。
如果答案超过10,输出-1。
dls orzz
想偷懒用set 结果T了
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#define read(x) scanf("%d",&(x))
using namespace std;
const int N=105;
int n;
inline int Tri(int _a,int _b,int _c){
int a=min(_a,min(_b,_c)),c=max(_a,max(_b,_c)),b=_a^_b^_c^a^c;
return (a-1)*n*n+(b-1)*n+c-1;
}
struct SS{
int tot,a[N*N*N],pos[N*N*N];
void insert(int x){ a[++tot]=x; pos[x]=tot; }
void erase(int x){ pos[a[tot]]=pos[x]; a[pos[x]]=a[tot]; tot--; }
bool empty(){ return tot==0; }
void clear(){ tot=0; }
}Set;
int Map[N][N];
#define T (Map[i][j]+Map[j][k]+Map[i][k])
inline void Add(int i,int j,int k){
if (T==2) Set.insert(Tri(i,j,k));
}
inline void Del(int i,int j,int k){
if (T==2) Set.erase(Tri(i,j,k));
}
inline void Rev(int i,int j){
for (int k=1;k<=n;k++) if (k!=i && k!=j) Del(i,j,k);
Map[i][j]^=1; Map[j][i]^=1;
for (int k=1;k<=n;k++) if (k!=i && k!=j) Add(i,j,k);
}
int ans;
inline void dfs(int st){
if (Set.empty()) ans=min(ans,st-1);
if (st>=ans) return;
int t=Set.a[1],c=t%n+1,b=t/n%n+1,a=t/n/n+1;
Rev(a,b); dfs(st+1); Rev(a,b);
Rev(b,c); dfs(st+1); Rev(b,c);
Rev(a,c); dfs(st+1); Rev(a,c);
}
int main(){
int TT,Case=0;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(TT);
while (TT--){
read(n);
for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) read(Map[i][j]);
for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++) for (int k=j+1;k<=n;k++) Add(i,j,k);
ans=11;
dfs(1);
printf("Case #%d: %d\n",++Case,ans==11?-1:ans);
Set.clear();
}
return 0;
}