【bzoj2466】[中山市選2009]樹 高斯消元
阿新 • • 發佈:2019-02-06
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; }