P2962 [USACO09NOV]灯Lights
贝希和她的闺密们在她们的牛棚中玩游戏。但是天不从人愿,突然,牛棚的电源跳闸了,所有的灯都被关闭了。贝希是一个很胆小的女生,在伸手不见拇指的无尽的黑暗中,她感到惊恐,痛苦与绝望。她希望您能够帮帮她,把所有的灯都给重新开起来!她才能继续快乐地跟她的闺密们继续玩游戏! 牛棚中一共有N(1 <= N <= 35)盏灯,编号为1到N。这些灯被置于一个非常複杂的网络之中。有M(1 <= M <= 595)条很神奇的无向边,每条边连接两盏灯。 每盏灯上面都带有一个开关。当按下某一盏灯的开关的时候,这盏灯本身,还有所有有边连向这盏灯的灯的状态都会被改变。状态改变指的是:当一盏灯是开著的时候,这盏灯被关掉;当一盏灯是关著的时候,这盏灯被打开。 问最少要按下多少个开关,才能把所有的灯都给重新打开。 数据保证至少有一种按开关的方案,使得所有的灯都被重新打开。
高斯消元
#include<bits/stdc++.h> typedef long long ll; const int inf=0x3f3f3f3f; #define For(i,a,b) for(int i=a;i<=b;i++) #define FFor(i,a,b) for(int i=a;i>=b;i--) template <class T> inline T min(T a,T b,T c) { return min(min(a,b),c); } template <class T> inline T max(T a,T b,T c) { return max(max(a,b),c); } template <class T> inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d)); } template <class T> inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d)); } using namespace std; const int N=1e3; const double eps=1e-9; //***********name************** int matrix[N][N]; int ans=inf; int n,m; int res[N]; //***********function********** void gauss() { For(i,1,n) { int t=i; For(j,i+1,n) if(matrix[j][i]) { t=j; break; } if(t!=i) For(j,1,n+1) swap(matrix[t][j],matrix[i][j]); For(j,i+1,n) { if(matrix[j][i]) For(k,1,n+1) matrix[j][k]^=matrix[i][k]; } } } void dfs(int cur,int tot) { if(ans<=tot)return; if(cur<1) { ans=min(ans,tot); return; } if(matrix[cur][cur]) { res[cur]=matrix[cur][n+1]; For(i,cur+1,n) res[cur]^=matrix[cur][i]&res[i]; if(res[cur]) dfs(cur-1,tot+1); else dfs(cur-1,tot); } else { res[cur]=0; dfs(cur-1,tot); res[cur]=1; dfs(cur-1,tot+1); } } //****************************** int main() { cin>>n>>m; For(i,1,m) { int a,b; scanf("%d%d",&a,&b); matrix[a][b]=1; matrix[b][a]=1; } For(i,1,n) matrix[i][i]=1,matrix[i][n+1]=1; gauss(); dfs(n,0); cout<<ans; return 0; }