ai表示每个节点是否按钮,根据每个点的情况列方程
总共得到n个未知数,n个方程
总共得到n个未知数,n个方程
经过高斯消元后,可能会出现自由元,2^S枚举自由元的选择,计算答案
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<bitset>
#define maxn 110
using namespace std;
bitset<210> a[maxn];
int c[maxn],b[maxn],ans[maxn];
int n,m,tot;
void gaosixiaoyuan()
{
memset(b,0,sizeof(b));
int k=1;
for (int i=1;i<=n;i++)
{
int now=k;
for (;now<=n;now++) if (a[now][i]==1) break;
if (now==n+1) {c[++tot]=i;continue;}
swap(a[now],a[k]);
for (int j=1;j<=n;j++) if (j!=k && a[j][i]) a[j]^=a[k];
b[i]=k++;
}
}
int calc(int x)
{
int cnt=0;
for (int i=1;i<=n;i++) ans[i]=a[i][n+1];
for (int i=1;i<=tot;i++)
if (x&(1<<(i-1)))
{
cnt++;
for (int j=1;j<=n;j++)
if (a[j][c[i]]) ans[j]=(!ans[j]);
}
for (int i=1;i<=n;i++) cnt+=ans[i];
return cnt;
}
int main()
{
scanf("%d",&n);
while (n)
{
for (int i=1;i<=n;i++) a[i].reset(),a[i][i]=1,a[i][n+1]=1;
for (int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[x][y]=1;a[y][x]=1;
}
tot=0;
gaosixiaoyuan();
int ans=n;
for (int i=0;i<(1<<tot);i++) ans=min(ans,calc(i));
printf("%d\n",ans);
scanf("%d",&n);
}
return 0;
}