【算法】高斯消元&線性代數
阿新 • • 發佈:2018-02-25
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; }
【算法】高斯消元&線性代數