数学上,高斯消元法(或译:高斯消去法),是线性代数规划中的一个算法,可用来为线性方程组求解。但其算法十分复杂,不常用于加减消元法,求出矩阵的秩,以及求出可逆方阵的逆矩阵。不过,如果有过百万条等式时,这个算法会十分省时。一些极大的方程组通常会用迭代法以及花式消元来解决。当用于一个矩阵时,高斯消元法会产生出一个“行梯阵式”。高斯消元法可以用在电脑中来解决数千条等式及未知数。亦有一些方法特地用来解决一些有特别排列的系数的方程组。
2968: Lights
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByte
Total Submit: 8 Accepted:1
Description
Bessie and the cows were playing games in the barn, but the power was reset and the lights were all turned off. Help the cows get all the lights back on so they can resume their games.
The N (1 ≤ N ≤ 35) lights conveniently numbered 1..N and their switches are arranged in a complex network with M (1 ≤ M ≤ 595) clever connection between pairs of lights (see below).
Each light has a switch that, when toggled, causes that light -- and all of the lights that are connected to it -- to change their states (from on to off, or off to on).
Find the minimum number of switches that need to be toggled in order to turn all the lights back on.
It‘s guaranteed that there is at least one way to toggle the switches so all lights are back on.
Input
* Line 1: Two space-separated integers: N and M.
* Lines 2..M+1: Each line contains two space-separated integers representing two lights that are connected. No pair will be repeated.
Output
* Line 1: A single integer representing the minimum number of switches that need to be flipped in order to turn on all the lights.
Sample Input
5 6
1 2
1 3
4 2
3 4
2 5
5 3
Sample Output
3
这个题我有两个思路一个是保存状态二分,但是显然时间很长
所以这种问题要使用高斯消元,高斯消元在解决矩阵的问题可是神神器,因为暴力得到某种状态的复杂度会很高
卿学姐的算法讲堂也有介绍这个,感兴趣的可以去看下学习下
他的引入是解方程,其实就是解矩阵,这个以前叫代入消元吧
#include<stdio.h> #include<algorithm> using namespace std; int n,m,ans=0x3f3f3f3f,a[37][37],x[37]; void gauss() { for(int k=1; k<=n; k++) { int bj=k; for(int i=k+1; i<=n; i++)if(a[i][k]) { bj=i; break; } if(bj!=k) for(int j=1; j<=n+1; j++) swap(a[bj][j],a[k][j]); for(int i=k+1; i<=n; i++) if(a[i][k]) { for(int j=1; j<=n+1; j++) a[i][j]^=a[k][j]; } } } void dfs(int xx,int tot) { if(tot>ans)return; if(!xx) { ans=min(ans,tot); return; } if(a[xx][xx]) { x[xx]=a[xx][n+1]; for(int j=n; j>xx; j--)x[xx]^=x[j]&a[xx][j]; if(x[xx])dfs(xx-1,tot+1); else dfs(xx-1,tot); } else { x[xx]=0; dfs(xx-1,tot); x[xx]=1; dfs(xx-1,tot+1); } } int main() { scanf("%d%d",&n,&m); for(int i=1; i<=m; i++) { int x,y; scanf("%d%d",&x,&y); a[x][y]=a[y][x]=1; } for(int i=1; i<=n; i++) a[i][n+1]=1,a[i][i]=1; gauss(); dfs(n,0); printf("%d",ans); return 0; }