bzoj 2466
裸的高斯消元解异或方程组问题
对于每个点列一个异或方程,所有影响这个点的点的对应系数为1,然后高消解一下就好
自由元用dfs处理,注意剪枝
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n; int a[105][105]; void Gauss() { for(int i=1;i<=n;i++) { int temp=i; while(!a[temp][i]&&temp<=n)temp++; if(temp>n)continue; if(temp!=i)for(int j=i;j<=n+1;j++)swap(a[temp][j],a[i][j]); for(int j=1;j<=n;j++)if(a[j][i]&&j!=i)for(int k=i;k<=n+1;k++)a[j][k]^=a[i][k]; } } int ans=0x3f3f3f3f; void dfs(int dep,int sum) { if(sum>=ans)return; if(!dep){ans=sum;return;} if(a[dep][dep])dfs(dep-1,sum+a[dep][n+1]); else { if(a[dep][n+1])return; dfs(dep-1,sum); for(int i=dep-1;i;i--)a[i][n+1]^=a[i][dep]; dfs(dep-1,sum+1); for(int i=dep-1;i;i--)a[i][n+1]^=a[i][dep]; } } int main() { while(1) { scanf("%d",&n); memset(a,0,sizeof(a)); if(!n)return 0; if(n==1){printf("1\n");continue;} int x,y; for(int i=1;i<n;i++)scanf("%d%d",&x,&y),a[x][y]=a[y][x]=a[i][n+1]=a[n][n+1]=a[i][i]=a[n][n]=1; Gauss(); ans=0x3f3f3f3f; dfs(n,0); printf("%d\n",ans); } return 0; }