高斯消元学模板

来源:互联网 发布:从哪里查淘宝消费总额 编辑:程序博客网 时间:2024/06/07 05:38

模板大法还是kuangbin的好啊!!

上我Final Bin的链接:点我学高斯消元模板


习题在对应的地方有,在这附录自己的学习记录:

POJ1830

学习的第一个高斯消元的模板题:关键是怎么构造矩阵,解释有如下两篇博客很细致:

http://www.cnblogs.com/fstang/archive/2013/01/24/2874231.html

http://blog.sina.com.cn/s/blog_62ebd4410100h2qf.html

看完了之后,相信自己也能把模板套出来,代码都一样的,就不贴了


HDOJ4818

首先熟悉解释下题意:题目中会定义一个传递矩阵,把自己的分数给“相邻”的其他人,然后问是不是“稳定”的。需要求一个位置上的人,能够让第n-1个位置上的人得到“稳定”后的最大价值


分析见:http://www.cnblogs.com/kuangbin/p/3568145.html


代码从我bin处学习的,里面添加了自己的注释和对题的理解:


/*Main Focus:Your friend A’s ID is always (n-1).If there are multiple qualifying persons, your friend A wants to know which one can increase his RP to the maximum extent.Each of these lines will contain two integers u and v (0 ≤ u, v < n), indicating u->v.*/double a[maxn][maxn],x[maxn];int equ,var;int Gauss(){int i,j,k,col,max_r;for(k=0,col=0;k<equ&&col<var;k++,col++){max_r=k;for(i=k+1;i<equ;i++)if (fabs(a[i][col])>fabs(a[max_r][col]))max_r=i;if (fabs(a[max_r][col])<eps) return 0;if (k!=max_r){for(j=col;j<var;j++)swap(a[k][j],a[max_r][j]);swap(x[k],x[max_r]);}x[k]/=a[k][col];for(j=col+1;j<var;j++) a[k][j]/=a[k][col];a[k][col]=1;for(i=0;i<equ;i++)if (i!=k){x[i]-=x[k]*a[i][k];for(j=col+1;j<var;j++)a[i][j]-=a[k][j]*a[i][col];a[i][col]=0;}}return 1;}vector<int> vec[maxn];int g[maxn][maxn],du[maxn],add[maxn];int main(){//input;int T,n,m;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);for(int i=0;i<=n;i++) vec[i].clear();memset(g,0,sizeof(g));memset(du,0,sizeof(du));int u,v;while(m--){scanf("%d%d",&u,&v);if (u==v) continue;g[u][v]=1;}for(int i=0;i<n;i++)for(int j=0;j<n;j++)if (j!=i&&g[i][j]){du[i]++;vec[j].push_back(i);}equ=var=n;//equ表示方程个数//var表示变量个数for(int i=0;i<n;i++) x[i]=0;memset(a,0,sizeof(a));for(int i=0;i<n;i++){a[i][i]=-1;//自己的人品是全部贡献出去的 int sz=vec[i].size();for(int j=0;j<sz;j++){int v=vec[i][j];if (i==v) continue;a[i][v]=1.0/du[v];//i赚的是从与i相连的所有点贡献的(均分)}}for(int i=0;i<n;i++) a[n-1][i]=1;x[n-1]=1;//这个就是题目中询问的是否能够恒成立for(int k=0;k<n-1;k++)if (g[n-1][k]==0){for(int i=0;i<n-1;i++)if (g[n-1][i])a[i][var]=1.0/(du[n-1]+1);//有边就分账 elsea[i][var]=0;//没边就清零 a[k][var]=1.0/(du[n-1]+1); a[n-1][var]=1;add[var]=k;//标记,这是从第k个人来的 var++;}if (!Gauss()){printf("INF\n");continue;}double tt=x[n-1];double now=x[n-1];int ans=-1;for(int i=n;i<var;i++)if (x[n-1]/a[n-1][i]>now){//满足更新ans=add[i];now=x[n-1]/a[n-1][i];}printf("%d %d\n",1,ans);}return 0;}


HDOJ3976

题解见:http://www.cnblogs.com/kuangbin/p/3428573.html

关键:a【u】【v】表示的是电流值

然后代码就能弄懂了

0 0