zoukankan      html  css  js  c++  java
  • HDU 4818 RP problem (高斯消元, 2013年长春区域赛F题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4818

    深深地补一个坑~~~

    现场赛坑在这题了,TAT。。。。

    今天把代码改了下,过掉了,TAT

    很明显的高斯消元的模型。

    现场一开始想的也大概是对的。

    根据度可以得到n个方程,加起来为1是一个方程,有一个是多余的。 加起来就是n个方程。

    只可能是无穷解和唯一解的情况。

    现场是先求解一遍,然后枚举所有可以加的,不停做高斯消元。

    但是因为高斯消元是O(n^3) 的, 再枚举的话就是n^4了。。。。

    这样做明显应该超时的,HDU交了这样做也是TLE,,,现场被坑死,一直返回WA,  然后程序就改得不成样子了。。。

    其实枚举那个可以省略。

    因为改变的就是最后一列。

    可以扩展矩阵,在后面多加几列。  然后变化之后,直接就得到了x(n-1)的值。

    只需要做一次高斯消元。

    代码君:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <queue>
      6 #include <map>
      7 #include <set>
      8 #include <vector>
      9 #include <string>
     10 #include <math.h>
     11 using namespace std;
     12 
     13 #define eps 1e-6
     14 const int MAXN=220;
     15 double a[MAXN][MAXN],x[MAXN];
     16 int equ,var;
     17 
     18 int Gauss()
     19 {
     20     int i,j,k,col,max_r;
     21     for(k=0,col=0;k<equ&&col<var;k++,col++){
     22         max_r = k;
     23         for(i=k+1;i<equ;i++)
     24             if(fabs(a[i][col])>fabs(a[max_r][col]))
     25                 max_r = i;
     26         if(fabs(a[max_r][col])<eps)return 0; //无解,有自由变元
     27         if(k != max_r){
     28             for(j=col;j<var;j++)
     29                 swap(a[k][j],a[max_r][j]);
     30             swap(x[k],x[max_r]);
     31         }
     32         x[k]/=a[k][col];
     33         for(j=col+1;j<var;j++)a[k][j]/=a[k][col];
     34         a[k][col] = 1;
     35         for(i=0;i<equ;i++)
     36             if(i!=k){
     37                 x[i] -= x[k]*a[i][k];
     38                 for(j=col+1;j<var;j++)a[i][j]-=a[k][j]*a[i][col];
     39                 a[i][col]=0;
     40             }
     41     }
     42     return 1;
     43 }
     44 
     45 vector<int>vec[MAXN];
     46 int g[MAXN][MAXN];
     47 int du[MAXN];
     48 int add[MAXN];
     49 
     50 
     51 int main()
     52 {
     53     //freopen("in.txt","r",stdin);
     54     //freopen("out.txt","w",stdout);
     55     int T;
     56     int n,m;
     57     scanf("%d",&T);
     58     while(T--)
     59     {
     60         scanf("%d%d",&n,&m);
     61         for(int i = 0;i < n;i++)
     62             vec[i].clear();
     63         memset(g,0,sizeof(g));
     64         memset(du,0,sizeof(du));
     65         int u,v;
     66         while(m--)
     67         {
     68             scanf("%d%d",&u,&v);
     69             if(u == v)continue;
     70             g[u][v] = 1;
     71         }
     72         for(int i = 0;i < n;i++)
     73         {
     74             for(int j = 0;j < n;j++)
     75                 if(j != i && g[i][j])
     76                 {
     77                     du[i]++;
     78                     vec[j].push_back(i);
     79                 }
     80         }
     81         equ = var = n;
     82         for(int i = 0;i < n;i++)
     83             x[i] = 0;
     84         memset(a,0,sizeof(a));
     85         for(int i = 0;i < n;i++)
     86         {
     87             a[i][i] = -1;
     88             int sz = vec[i].size();
     89             for(int j = 0;j < sz;j++)
     90             {
     91                 int v = vec[i][j];
     92                 if(i == v)continue;
     93                 a[i][v] = 1.0 / du[v];
     94             }
     95         }
     96         for(int i = 0;i < n;i++)
     97             a[n-1][i] = 1;
     98         x[n-1] = 1;
     99 
    100 
    101         for(int k = 0;k < n-1;k++)
    102             if(g[n-1][k] == 0)
    103             {
    104                 for(int i = 0;i < n-1;i++)
    105                 {
    106                     if(g[n-1][i])a[i][var] = 1.0/(du[n-1]+1);
    107                     else a[i][var] = 0;
    108                 }
    109                 a[k][var] = 1.0/(du[n-1]+1);
    110                 a[n-1][var] = 1;
    111                 add[var] = k;
    112                 var++;
    113             }
    114 
    115         if(!Gauss())
    116         {
    117             printf("INF
    ");
    118             continue;
    119         }
    120         double tt = x[n-1];
    121         double now = x[n-1];
    122         int ans = -1;
    123         for(int i = n;i < var;i++)
    124         {
    125             if(x[n-1]/a[n-1][i] > now)
    126             {
    127                 ans = add[i];
    128                 now = x[n-1]/a[n-1][i];
    129             }
    130         }
    131         printf("%d %d
    ",1,ans);
    132     }
    133     return 0;
    134 }
  • 相关阅读:
    Android防止按钮连续点击
    Android中的AlertDialog遇到的错误
    android通过Jni加载so库遇到UnsatisfiedLinkError问题!!!
    接口回调
    Android中的APinner2
    AndroidAPI
    Android中的下拉列表
    学习地址
    2018/12/21:Date类
    2018/12.21:找出数组最大项和最小项。
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3568145.html
Copyright © 2011-2022 走看看