[Usaco2009 Nov]lights(高斯消元)

luogu

点灯游戏应该很多人都在小时候頽过吧

反正我直到现在也不会

很明显一个灯最多只需要点一次

然后高斯消元

解完肯定剩自由元(就是那些全是0的行)

然后这些都爆搜

由于剩下的自由元不会太多

所以时间复杂度$O(能过)$

以上

 1 #include<cstdio>
 2 #include<algorithm>
 3 using std::swap;
 4 const int N=40;
 5 template<typename tp>void read(tp &kk){
 6     tp ret=0,f=1;char ch=getchar();
 7     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 8     while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
 9     kk=ret*f;
10 }
11 int n,a[N][N];
12 
13 
14 void gauss()
15 {
16     for(int l=1;l<=n;l++)
17     {
18         int g=l;
19         while(g<=n&&(!a[g][l])) g++;
20         if(g>n) continue;
21         if(l!=g)
22             for(int i=l;i<=n+1;i++) swap(a[l][i],a[g][i]);
23         for(int i=1;i<=n;i++)
24         {
25             if(a[i][l]&&i!=l)
26             {
27                 for(int j=l;j<=n+1;j++) a[i][j]^=a[l][j];
28             }
29         }
30     }
31 }
32 
33 int ans;
34 void wtf(int l,int x)
35 {
36     if(x>ans) return;
37     if(!l){ans=x;return;}
38     if(a[l][l]) wtf(l-1,x+a[l][n+1]);
39     else
40     {
41         if(a[l][n+1]) return;
42         wtf(l-1,x);
43         for(int i=l-1;i;i--) a[i][n+1]^=a[i][l];
44         wtf(l-1,x+1);
45         for(int i=l-1;i;i--) a[i][n+1]^=a[i][l];
46     }
47 }
48 int m,xi,yi;
49 int main()
50 {
51     read(n),read(m);
52     for(int i=1;i<=n;i++) a[i][i]=a[i][n+1]=1;
53     for(int i=1;i<=m;i++)
54     {
55         read(xi),read(yi);
56         a[xi][yi]^=1,a[yi][xi]^=1;
57     }
58     gauss();
59     ans=n;
60     wtf(n,0);
61     printf("%d\n",ans);
62     return 0;
63 }
orz

猜你喜欢

转载自www.cnblogs.com/rikurika/p/light.html
今日推荐