您的位置:首页 > 其它

UVA 10828 - Back to Kernighan-Ritchie(线性方程组jordan消元)

2017-05-10 22:58 441 查看

题目链接

10828 - Back to Kernighan-Ritchie

分析

白书经典题目,每一个顶点用期望的线性性质列出方程.不过要注意特殊情况以及结合具体含义来分析,用gauss_jordan消元(转化为阶梯阵)之后.若有一行A[i][i]=0并且A[i]
=0,则说明此点不可被访问0次.继续若有矛盾方程A[i][i] = 0而A[i]
不等于0则说明A[i][i]无解即不可能访问到终太,达到无限大.同时若有一个无解变量在某一个方程中当前元肯定无解.

AC code

#include <cstdio>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <set>
#include <iomanip>
#include <bitset>
#define pb push_back
#define mp make_pair
#define PI acos(-1)
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define INF64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int MOD = 1e9+7;
const int MAX_P = 2e4+10;
const int maxn = 100+10;
const int MAX_V = 5e5+10;
const double eps = 1e-8;
typedef long long LL;
typedef long double DB;
typedef pair<int,int> Pair;
typedef double Matrix[maxn][maxn];
int n;
//消元为对角阵
void gauss_jordan(Matrix A,int n){
//A增广矩阵,第n列是结果列
for(int i=0 ; i<n ; ++i){
int r = i;//元素最大列
for(int j = i+1 ; j<n ; ++j)
if(abs(A[j][i]) > abs(A[r][i]))r = j;
if(abs(A[r][i]) < eps)continue;
if(r!=i)for(int j = 0 ; j<=n; ++j)swap(A[r][j],A[i][j]);//交换
//与i行以外的所有行消元,化为阶梯阵,与gauss消元的不同
for(int k=0 ; k<n ; ++k)
if(k!=i)
for(int j = n ; j>=i ; --j)A[k][j] -=A[k][i]/A[i][i]*A[i][j];//精度.
}
}
Matrix A;
int d[maxn];//出度
std::vector<int> p[maxn];//前驱
int inf[maxn];//无穷记号
int main() {

int kase =0;
while (scanf("%d",&n )&&n) {
int x,y;
for(int i=0 ; i<n ; ++i)p[i].clear();
memset(d,0,sizeof(d));
memset(A,0,sizeof(A));
memset(inf,0,sizeof(inf));
while (scanf("%d%d",&x,&y ) && x) {
--x,--y;
++d[x];
p[y].pb(x);
}
//构照方程组
for(int i=0 ; i<n ; ++i){
A[i][i] = 1;
for(int j=0 ; j<p[i].size() ; ++j){
A[i][p[i][j]]=-1.0/d[p[i][j]];
}
}
A[0]
= 1;
gauss_jordan(A,n);

for(int i=n-1 ; i>=0 ; --i){
if(abs(A[i][i]) <eps &&abs(A[i]
)>eps)inf[i] = 1;
for(int j=i+1 ; j<n ; ++j)
if(abs(A[i][j])>eps && inf[j])inf[i] =1;
}
int q;
printf("Case #%d:\n", ++kase);
scanf("%d",&q );
while (q--) {
int x;scanf("%d",&x );
--x;
if(inf[x])puts("infinity");
else printf("%.3lf\n", abs(A[x][x])<eps?0.000 : A[x]
/A[x][x]);
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gauss 数学