1. 程式人生 > >【算法】高斯消元&線性代數

【算法】高斯消元&線性代數

for baidu == getchar 算法 print 密碼 mes pos

寒假作業~就把文章和題解3道題的代碼扔在這裏啦——鏈接: https://pan.baidu.com/s/1kWkGnxd 密碼: bhh9

1.HNOI2013遊走

#include <bits/stdc++.h>
using namespace std;
#define maxn 600
#define db double
int n, m, degree[maxn];
db f[maxn][maxn], ans[maxn], fans;
bool dis[maxn][maxn];

struct edge
{
    int x, y;
    db ans;
}R[maxn * maxn];

int read() { int x = 0, k = 1; char c; c = getchar(); while(c < 0 || c > 9) { if(c == -) k = -1; c = getchar(); } while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = getchar(); return x * k; } bool cmp(edge a, edge b) { return a.ans > b.ans; }
void Gauss() { for(int i = 1; i <= n; i ++) { int now = i, j = i; for(int j = i + 1; j <= n; j ++) if(fabs(f[j][i]) > fabs(f[now][i])) now = j; if(i != now) { for(int k = 1; k <= n + 1; k ++) swap(f[i][k], f[now][k]); }
for(int j = i + 1; j <= n + 1; j ++) f[i][j] /= f[i][i]; for(int j = 1; j <= n; j ++) { if(j == i) continue; for(int k = i + 1; k <= n + 1; k ++) f[j][k] -= f[j][i] * f[i][k]; } } } int main() { n = read(), m = read(); for(int i = 1; i <= m; i ++) { int x = read(), y = read(); R[i].x = x, R[i].y = y; degree[x] ++, degree[y] ++, dis[x][y] = dis[y][x] = true; } n -= 1; for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) if(dis[i][j]) f[i][j] = - (1 / (db) degree[j]); else if(i == j) f[i][j] = 1; f[1][n + 1] = 1; Gauss(); for(int i = 1; i <= n; i ++) ans[i] = f[i][n + 1]; for(int i = 1; i <= m; i ++) R[i].ans = ((db) ans[R[i].x] / (db) degree[R[i].x]) + ((db) ans[R[i].y] / (db) degree[R[i].y]); sort(R + 1, R + 1 + m, cmp); for(int i = 1; i <= m; i ++) fans += (db) i * R[i].ans; printf("%.3lf\n", fans); return 0; }

2.USACO燈

#include <bits/stdc++.h>
using namespace std;
#define maxn 60
int n, m, a[maxn][maxn], ans[maxn], fans = 999999, tot;

int read()
{
    int x = 0, k = 1;
    char c;
    c = getchar();
    while(c < 0 || c > 9) { if(c == -) k = -1; c = getchar(); }
    while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = getchar();
    return x * k;
}

void Gauss()
{
    for(int i = 1; i <= n; i ++)
    {
        int now = i, j = i;
        while(j <= m && !a[j][i]) j ++;
        if(j > m) continue;
        if(now != j)
        {
            for(int k = 1; k <= n + 1; k ++)
                swap(a[now][k], a[j][k]);
        }
        for(int j = 1; j <= n; j ++)
            if(j != i && a[j][i])
            {
                for(int k = 1; k <= n + 1; k ++)
                    a[j][k] ^= a[i][k];
            }
    }
}

void dfs(int now)
{
    if(tot >= fans) return;
    if(!now)
    {
        fans = min(fans, tot);
        return;
    }
    if(a[now][now]) //不是自由元 
    {
        int tem = a[now][n + 1];
        for(int i = now + 1; i <= n; i ++)
            if(a[now][i]) tem ^= ans[i];
        ans[now] = tem;
        if(tem) tot ++; 
        dfs(now - 1); 
        if(tem) tot --;
    }
    else 
    {
        ans[now] = 0;
        dfs(now - 1);
        tot ++;
        ans[now] = 1;
        dfs(now - 1);
        tot --;
    }
}

int main()
{
    n = read(), m = read();
    for(int i = 1; i <= n; i ++)
        a[i][i] = 1, a[i][n + 1] = 1;
    for(int i = 1; i <= m; i ++)
    {
        int x = read(), y = read();
        a[x][y] = 1, a[y][x] = 1;
    }
    Gauss();
    dfs(n);
    printf("%d", fans);
} 

3.NOIP2004蟲食算

#include <bits/stdc++.h>
using namespace std;
#define maxn 40
int n, f[maxn][maxn], g[maxn][maxn], d[maxn], x[maxn];
char s[3][maxn];
bool vis[maxn], flag;

int GCD(int x, int y)
{
    int z;
    while(y)
    {
        z = x % y;
        x = y, y = z;
    }
    return x;
}

int LCM(int x, int y)
{
    return (x * y / GCD(x, y));
} 

void check()
{
    memset(vis, 0, sizeof(vis));
    for(int i = 1; i <= n; i ++)
    {
        int sum = 0;
        for(int j = 2; j <= n; j ++)
            sum += d[j] * g[i][j];
        if(sum % f[i][i]) return;
        sum /= f[i][i];
        if(sum < 0 || sum >= n || vis[sum]) return;
        vis[x[i] = sum] = true;
    }
    flag = true;
}

void solve()
{
    for(int p = 1; p <= n; p ++)
    {
        int now = p;
        for(int i = p + 1; i <= n; i ++)
            if(abs(f[i][p]) > abs(f[now][p])) now = i;
        if(now != p)
        {
            for(int i = 1; i <= n; i ++)
                swap(f[now][i], f[p][i]), swap(g[now][i], g[p][i]);
        } 
        for(int i = 1; i <= n; i ++)
            if(i != p && f[i][p])
            {
                int lcm = LCM(f[i][p], f[p][p]);
                int d1 = lcm / f[i][p], d2 = lcm / f[p][p];
                for(int j = 1; j <= n; j ++)
                {
                    f[i][j] = f[i][j] * d1 - f[p][j] * d2;
                    g[i][j] = g[i][j] * d1 - g[p][j] * d2;
                }
            }
    }
}

void dfs(int u)
{
    if(u == 1) 
    {
        check();
        if(flag)
        {
            for(int i = 1; i < n; i ++)
                printf("%d ", x[i]);
            printf("%d\n", x[n]);
            exit(0);
        }
        return;
    }
    d[u] = 0, dfs(u - 1);
    d[u] = 1, dfs(u - 1);
}

int main()
{
    scanf("%d", &n);
    scanf("%s%s%s", s[0] + 1, s[1] + 1, s[2] + 1);
    for(int i = 1; i <= n; i ++)
        for(int j = 0; j <= 2; j ++)
            if(j < 2) f[i][s[j][i] - A + 1] += 1;
            else f[i][s[j][i] - A + 1] -= 1;
    for(int i = 1; i <= n; i ++)
        g[i][i] = n, g[i][i + 1] = -1;
    solve();
    dfs(n);
    return 0;
} 

【算法】高斯消元&線性代數