zoukankan      html  css  js  c++  java
  • 线代之高斯消元

    数学上,高斯消元法(或译:高斯消去法),是线性代数规划中的一个算法,可用来为线性方程组求解。但其算法十分复杂,不常用于加减消元法,求出矩阵的秩,以及求出可逆方阵的逆矩阵。不过,如果有过百万条等式时,这个算法会十分省时。一些极大的方程组通常会用迭代法以及花式消元来解决。当用于一个矩阵时,高斯消元法会产生出一个“行梯阵式”。高斯消元法可以用在电脑中来解决数千条等式及未知数。亦有一些方法特地用来解决一些有特别排列的系数的方程组。

    2968: Lights 分享至QQ空间

    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;
    }
  • 相关阅读:
    动态网络社团检测学习笔记 --- 随机块模型小结之简介
    十五组第四次作业
    17现代软件工程十五组第二次作业
    17现代软件工程十五组第三次作业
    现代软件工程2017十五组成员介绍
    软件测试学习日志3 ————软件测试作业之控制流图
    软件测试学习日志———— round 2 Junit+intellj idea 安装及简单的测试使用
    软件测试学习日志————round 1 some questions of two small programs
    [关于printPrime是()方法的控制流图和点覆盖、边覆盖、主路径覆盖]
    【在myeclipse中使用Junit(4.12), Hamcrest(1.3) 和Eclemma】
  • 原文地址:https://www.cnblogs.com/BobHuang/p/7450565.html
Copyright © 2011-2022 走看看